Traits
Every trait in OODS Foundry 0.10.1: 49. A trait adds fields and says what to show in each context. Define it once, and every object that has it gets it.
Generated from @oods/foundry 0.10.1
behavioral
- Filterable
Adds multi-facet filtering to list and collection views. Filterable injects a filter panel into the sidebar or header region, wires filter state to the data layer, and provides semantic token mappings for consistent filter UI styling across brands. Filters are defined as an array of filter descriptors, each specifying a field, operator, and available values. Active filters are tracked separately for apply/clear lifecycle. The trait supports both immediate-apply and batch-apply modes for UX flexibility.
- Pageable
Adds pagination controls to list and collection views. Pageable injects a pagination bar into the footer region, wires page state to the data layer, and provides semantic token mappings for consistent pagination UI styling across brands. The trait supports configurable page sizes, total item counts for page calculation, and both simple (prev/next) and full (goto page) navigation modes. Page state is managed via the page and pageSize props, which the consuming layout binds to data offset/limit parameters or API pagination cursors.
- Searchable
Adds full-text search capability to list and collection views. Searchable injects a search input into the header region, wires query state to the data layer, and provides semantic token mappings for consistent search UI styling across brands. The trait supports placeholder text customization, debounce control for performance, and clear-on-escape behavior. Search state is managed via the searchQuery prop, which the consuming layout binds to a data filter or API parameter.
- Sortable
Adds column sorting controls to list and table views. Sortable injects sort indicators into the header region near column headers, wires sort state to the data layer, and provides semantic token mappings for consistent sort UI styling across brands. The trait supports single-column sorting with ascending/descending/none cycle. Sort state is managed via sortField and sortDirection props, which the consuming layout binds to data ordering parameters or API sort queries.
- Taggable
Adds configurable tag management with guardrails for custom authoring, taxonomy alignment, and tag governance. Taggable supports both open tagging (user-defined) and controlled vocabularies (allow-list), with optional moderation workflows for tag quality control. Tags are first-class metadata in OODS — they drive discovery, filtering, and cross-object relationships. The trait provides per-tag governance metadata (creator, creation date, usage count) for taxonomy health monitoring, and optional synonym resolution to prevent tag fragmentation (e.g., "javascript" and "js" resolve to the same canonical tag).
communication
- Communicable
Canonical communication trait that unifies multi-channel delivery, template governance, delivery policies, and threaded conversations derived from R20.1/R20.6 research. Provides orchestration-ready schemas for channels, messages, policies, and conversations with Preferenceable/Authable/Classifiable integration points.
content
- Labelled
Canonical label, description, and placeholder copy for authored objects. Labelled is a foundational content trait used by Organization, Product, Relationship, and other core objects to provide consistent text display across all view contexts. Supports configurable length constraints, required/optional description, and copy variants (e.g., primary, short, formal) for context-sensitive text rendering.
core
- Addressable
Canonical multi-role address trait with validation metadata, geocoding, and international formatting hooks. Provides a single, reusable capability for billing, shipping, warehouse, and office addresses.
- Assessable
Records what an assessment concluded about a record — its result state — as something other than a verdict colour. A result is not binary. An accessibility engine returns four kinds of answer for every rule on every page: it found a violation, it found nothing wrong, it could not decide and a person must look, or the rule does not apply there. A fifth is the one engines drop: the check never ran. Lighthouse carries the same shape as score display modes (binary, manual, notApplicable, error). A real capture run records all four axe answers — violations as items, and needs-review, passing and not-applicable as page-level counts (28, 2,029 and 1,531) — and Deque warns that implementations drop the incomplete ones. That is why this is its own trait rather than a Stateful state set: it is not a lifecycle a record moves through, it is what one reading concluded, and the non-verdicts are the part most often lost. The rule that matters is visual. A result state renders as its OWN visual family, never the severity family: never red, never green, never scored. The moment "needs review" looks like a failure, someone reports it as one; the moment "passed" looks like a success badge, a count of 2,029 passes reads as a grade. The composer enforces it (`enforceResultStateFamily`): every StatusBadge or Badge bound to `result_state` carries the result tone from @oods/component-contracts, and a component that cannot carry a tone is refused (OODS-V211). A spec fails if any theme scope resolves that tone to a severity colour. The field is `result_state`, not `status`, so an object can carry a lifecycle through Stateful and a result through this trait without the two colliding (the Supersedable precedent). Severity is a separate fact about a violation (Finding.impact) and is never folded into the result state. Artifact assessments also record measured (the measurement ran), measured_zero (it ran and found none) and unknown (the historical record contains no result). A zero is evidence of measurement, never a missing check. These states use the same neutral family and carry no inferred grade. Not adopted, with the reason: low-confidence (no capture artifact carries a confidence for a result; the Confidence-bearing trait is not authored until a screen needs it); Lighthouse's informative (it states no verdict and no capture record carries one); any numeric score (a score is a verdict colour in another form).
- Authable
Role-based access control extension pack grounded in the R21.2 membership pattern. Encodes roles, permissions, memberships, and adjacency edges for tenant-aware RBAC.
- Classifiable
Canonical taxonomy + folksonomy trait supporting taxonomy, tag, and hybrid modes with governance metadata.
- Preferenceable
User preference trait backed by JSONB storage, schema versioning, and registry governance. Encodes namespaces such as theme, notifications, and display with deterministic overrides.
- Provenanced
Carries how a record's values were obtained, beside the values, wherever the record travels. Two values obtained differently are not comparable: a route an agent inferred from a URL and a route an OpenAPI document declares can hold the same string and mean different things, and a screen that shows one beside the other unlabelled publishes a false equivalence. A captured finding is only as good as the engine, the version, the file and the moment behind it. OODS Foundry already carries this shape twice, and this trait is factored from them rather than inventing a third. The observation rows name the capture run, the target, the artifact kind and read path, and the capture time beside each row; the preview's context panel names each item's source, id, the query that found it and when it was fetched. What both say is the same five things: which source, which record in it, where in that record, how, and when. Those are the five fields here: provenance_source who produced it observation: the capture tool context: source provenance_record which record there observation: runId context: id provenance_locator where in that record observation: readPath context: query provenance_method how the value was obtained observation: artifactKind context: (the search) provenance_at when observation: capturedAt context: fetchedAt The method is the field that separates this from a citation: "axe-core 4.11.0", "route_derived", "openapi_declared", "sha256 attested by the run manifest". The observation rows and context items keep their own stored shapes for now. An absent value means not recorded, never "no provenance needed". A record with no provenance_source is not shown as sourced.
domain
- SaaSBillingBillable
Normalizes recurring price configuration for SaaS plans including cadence, currency, and trial policy. NOTE (trait-split gap): this domain trait does NOT model proration — no supportProration/proration_amount/proration_date/prorationBehavior. A Subscription composing only SaaSBillingBillable silently cannot prorate. To enable proration, compose the CORE financial/Billable trait (which owns the proration semantics). See traits/financial/Billable.trait.yaml.
- SaaSBillingMetered
Provides usage metering fields for consumption based billing with normalized units and rollover policy.
- SaaSBillingPayable
Captures invoice level billing terms, status, and outstanding balance metadata for SaaS finance teams.
- SaaSBillingRefundable
Describes refund eligibility, policy windows, and credit memo tracking for SaaS billing flows.
financial
- Billable
Recurring billing mechanics trait that normalizes cycle tracking, payment timing, and period management for subscription-based entities. Billable owns the billing CYCLE — when payments occur, how periods progress, and what the payment state is. DISTINCT from Priceable — Priceable handles PRICING (amount, currency, models). Billable handles RECURRENCE (cycles, periods, payment timing, proration). A Subscription composes both: Priceable for "how much" and Billable for "when/how". Core concepts: - Billing Cycle: current_period_start → current_period_end with progress tracking - Payment Timing: prepaid (charge at period start) vs postpaid (charge at period end) - Proration: fractional billing when mid-cycle changes occur, with preview/commit timing (proration_date), a charge-timing policy (prorationBehavior), and billing-anchor-reset disclosure - Payment Status: tracks the outcome of the most recent collection attempt - Cycle Anchoring: fixed day-of-month for consistent renewal dates PRORATION SCOPE (trait-split gap): proration semantics live ONLY on this CORE financial/Billable trait. The saas-billing domain trait SaaSBillingBillable (domains/saas-billing/traits/billable.trait.yaml) does NOT expose proration, so a Subscription composing only SaaSBillingBillable silently CANNOT prorate. To enable proration for a SaaS subscription, compose financial/Billable (as the core Subscription object does, alias SubscriptionBilling).
- Priceable
Introduces monetization metadata with currency handling, pricing models, and billing cadence semantics.
lifecycle
- Archivable
Provides archival lifecycle management with configurable retention, restoration, audit tracking, and compliance metadata. Archivable manages the full archive-restore-purge lifecycle, including soft-delete with configurable duration before hard deletion, partial restoration support, and per-archive compliance tagging. Objects composing Archivable can be soft-deleted (moved to an "archived" state with full data retention), restored within a configurable window, or permanently purged after the retention period expires. The trait tracks who archived the entity, why, and through what method (manual, automated, policy) for audit trail completeness.
- Auditable
Compliance-grade audit trail trait that captures state transitions with actor, reason, and timestamp metadata. Auditable observes Stateful transitions and records them as an append-only audit log suitable for compliance review, debugging, and timeline rendering. Auditable defines the INTERFACE for audit data — the schema shape, parameters, and view extensions that match the existing implementation. Advanced compliance features (crypto-shredding, KMS integration, tamper-proof hashing) are documented in R21.3 research and targeted for future enrichment. Core concepts: - Audit Log: append-only array of AuditEntry records - Transition Capture: from_state → to_state with timestamp, actor, and reason - Retention Policy: configurable retention period for log entries - Actor Tracking: optional actor_id capture for accountability - Reason Enforcement: optional requirement for transition justification
- Cancellable
Adds lifecycle-aware cancellation workflows with policy guardrails and semantic token mappings.
- Stateful
Normalizes lifecycle state transitions, exposes canonical status semantics, and provides optional transition governance for production workflows. Many objects compose Stateful (User, Subscription and Product among them), and it serves as the data source for the Colorized visual trait. At its simplest, Stateful defines an ordered list of valid states and tracks the current status. When governance is enabled via transitionRules, it additionally enforces which transitions are allowed, records the actor and reason for each transition, and materializes the set of valid next states — making it suitable for auditable workflows where arbitrary state jumps are not permitted.
- Supersedable
Records that one record replaces another of the same kind, and which of them still stands. Supersession is a self-referencing lineage, not a workflow: a record does not move through supersession, it is replaced by a later record, and the pair stays readable afterwards. That is why it is its own trait rather than a Stateful state set — Stateful governs transitions between states of one record, while Supersedable relates two records and keeps both. Two stores already hold that shape and they record it from opposite ends. A decision store writes the forward pointer (`superseded_by`, the replacement's id) beside a status of active | superseded | archived | stale. OODS Foundry's own composition acceptances write the backward pointer (`supersedes`, the acceptance this one replaced, with the time it was accepted) and leave the standing acceptance implicit. The trait therefore declares both pointers and a `recordedDirection` parameter naming which one the source of truth actually writes; the other is derived where the store can derive it and left absent where it cannot. An absent pointer means unknown, never "nothing was superseded". The field is `supersession_status`, not `status`, so an object can carry its own lifecycle through Stateful and its supersession through this trait without the two colliding.
- Timestampable
Captures creation and update timestamps with configurable audit metadata for lifecycle tracking.
structural
- Ownerable
Adds ownership metadata linking entities to their governing account or principal with transfer auditing.
visual
- Colorized
Maps lifecycle states to semantic color tokens for consistent status theming across the design system. Colorized is the visual bridge between the Stateful trait's data model and the OODS token system's three-tier architecture (ref → theme → system → component). Every object that composes Stateful should also compose Colorized so that status values resolve to a deterministic set of surface, border, text, and icon tokens. The trait encodes WCAG contrast enforcement, color-blind safety via redundant icon+text cues, and theme-aware OKLCH token resolution — ensuring status communication never relies on color alone.
- Statusable
Semantic status presentation layer that maps business statuses to visual tones, design tokens, and badge/banner rendering. Statusable owns the status registry pattern: a domain-scoped lookup table that translates raw status strings into consistent visual output (tone, label, icon, token sets). DISTINCT from Stateful — Stateful governs state machine transitions and guards; Statusable governs how status LOOKS. Statusable is the bridge between data-layer state and the component layer (Badge, Banner, StatusBadge). Core concepts: - Status Registry: Map<domain, Map<status, StatusPresentation>> - Tone System: Six semantic tones (neutral, info, accent, success, warning, critical) - Token Resolution: --cmp-status-{tone}-{surface|border|text} CSS variables - Domain Scoping: Each domain (subscription, invoice, ticket, etc.) has its own status map - Emphasis Variants: badge.subtle / badge.solid, banner.subtle / banner.solid
viz.encoding
- EncodingColor
Maps a data field to chromatic encodings using governed palettes and redundant channels to fulfill RDV.4 accessibility equivalence rules.
- EncodingOpacity
Constant Cartesian mark opacity
- EncodingPositionX
Binds a data field to the horizontal axis. Declares allowed data types, scale defaults, and accessibility metadata to satisfy Normalized Viz Spec requirements.
- EncodingPositionY
Binds a data field to the vertical axis. Provides normalization, default scale hints, and a11y metadata for describing quantitative measures.
- EncodingShape
Categorical shape encoding
- EncodingSize
Maps a quantitative field to glyph size (radius or area) with governed ranges that can be validated for perceptual correctness and accessibility.
viz.interaction
- InteractionHighlight
Emphasizes hovered or selected points by adjusting a configurable visual property.
- InteractionTooltip
Shows contextual details-on-demand when focusing or hovering a specific datum.
viz.layout
- LayoutConcat
Defines dashboard-style concatenation for coordinated multi-view experiences.
- LayoutFacet
Repeats a normalized visualization spec across a governed facet grid so row and column groupings stay synchronized with shared color/scale semantics.
- LayoutLayer
Governs sequencing, blending, and shared channel behavior for layered mark compositions.
viz.mark
- MarkArea
Canonical area mark for cumulative totals and ranges. Fills the region between the series baseline and value curve with configurable opacity and interpolation.
- MarkBar
Canonical rectangular mark for magnitude comparisons. Supports stacked or grouped categories and enforces RDS.7 accessibility requirements for redundant encodings.
- MarkGraph
Read-only force graph over a declared neighborhood edge array, rendered by public viz.render.
- MarkLine
Canonical line mark for trends, rates, and progressions. Encodes values as connected segments with configurable curve smoothing and join policies.
- MarkPoint
Canonical point mark for scatterplots and overlays. Encodes each datum as a discrete glyph with configurable shape, size, and fill semantics.
- MarkRect
Heatmap authoring over the existing MarkRect renderer
viz.pattern
- ScatterPlot
Scatter authoring over the existing MarkPoint renderer
viz.scale
- ScaleLinear
Shared linear/continuous scale definition used by positional, color, and size encodings. Provides normalized domain/range metadata plus zero baseline enforcement per RDV.3 findings.
- ScaleTemporal
Temporal scale metadata with UTC rendering. Version 0.3.0 removes the unused timezone parameter (breaking); axes and tooltips continue to render in UTC.
viz.spatial
- Geocodable
Indicates that data contains location-resolvable information that can be mapped to coordinates or geographic boundaries. Supports auto-detection of geo fields based on naming patterns and field types.