Documentation

Infrastructure

31 behaviors · std/behaviors

On this page

atoms

std-anim-tick

sprite animation clock atom. Owns a global animation counter and exposes the current frame NAME (@entity.frameName = frames[counter % len]) every 100ms tick. Boards compose it via uses + a trait-ref rebound (linkedEntity) to the board entity; render-ui merges @entity.frameName onto the animated sprite's asset, replacing the inlined animTick frame counters that were duplicated across game boards. 1.1.0 redesign: the 1.0.0 units-frame-advance / effects-aging sets were removed — numeric unit frames served the pre-animation-contract regime (draw-sprite paints atlas sub-texture NAMES, which is exactly what frameName now exposes; zero consumers existed), effects aging is owned by std-fx-particles, and the shared-entity one-writer rule (ORB_SHARED_ENTITY_FIELD_CONFLICT) forbids a shared atom co-writing fields a board's own ticks also write. Tick interval is a language-level literal (100ms); the config surface is frames.

lolo
1 uses AnimTick from "std/behaviors/std-anim-tick"

Entity: AnimTickItem (runtime)

Traits

Traiteventsemits
AnimTicknonenone

Config knobs

TraitKnobTypeLabel
AnimTickframes[string]Frame names

std-approval-gate

generic approval gate / approver workflow. Use when a user voices that an action must be reviewed, approved, signed off, or authorized by a privileged role before it proceeds (admin approval, supervisor sign-off, manager approval, gatekeeper review, editor approval, senior editor approval, reviewer approval, publishing approval, draft approval, content review, submit drafts then editors review and approve or reject, needs approval before going live, requires sign-off before publish). Persists ApprovalRequest rows + surfaces the PENDING ones in a review queue showing what is being approved and who asked, with Approve / Deny actions — Deny captures a written reason. approverRoles is ENFORCED by the review transitions themselves: an APPROVE/DENY from a viewer whose role is not listed does not fire. blockSelfApproval additionally stops a reviewer approving their own request (four-eyes) — DENY stays allowed as self-withdrawal. On approval emits ApprovalGranted; on denial emits ApprovalDenied (with the reason). Hosts that replay the gated action MUST route a failed replay back via APPROVAL_REPLAY_FAILED so the request reopens instead of being silently consumed. Compose onto any orbital whose action you want to gate: the target orbital emits an external event, an ApprovalRequest row is created (stamp subjectLabel/subjectId/requestedBy so reviewers see what they are judging), and downstream effects wait on ApprovalGranted. Differs from std-mod-queue, which is content-moderation-specific.

lolo
1 uses ApprovalGate from "std/behaviors/std-approval-gate"

Entity: ApprovalRequest (persistent)

Traits

Traiteventsemits
LoadingSpinnernonenone
ErrorSpinnernonenone
LoadingTextnonenone
ShieldCheckIconnonenone
ApprovalQueueTitlenonenone
DenyReasonTitlenonenone
DenyReasonHintnonenone
CloseButtonnonenone
ApprovalDividernonenone
ErrorAlertnonenone
ApprovalGateReviewAPPROVAL_REPLAY_FAILED, OPENAPPROVE, DENY, OPEN_SUBJECT, CONFIRM_DENY, CANCEL_DENY, CLOSE, ApprovalGranted, ApprovalDenied, ApprovalRequestLoaded, ApprovalRequestLoadFailed, ApprovalRequestReviewed, ApprovalRequestReviewFailed

Config knobs

TraitKnobTypeLabel
ErrorSpinnersizeunknown
LoadingTextcolorunknown
LoadingTextcontentunknown
LoadingTextvariantunknown
ShieldCheckIconnameunknown
ApprovalQueueTitlecontentunknown
ApprovalQueueTitlevariantunknown
DenyReasonTitlecontentunknown
DenyReasonTitlevariantunknown
DenyReasonHintcolorunknown
DenyReasonHintcontentunknown
DenyReasonHintvariantunknown
CloseButtonactionunknown
CloseButtoniconunknown
CloseButtonlabelunknown
CloseButtonvariantunknown
ErrorAlertmessageunknown
ErrorAlertvariantunknown
ApprovalGateReviewapproverRoles[string]Who can approve requests?
ApprovalGateReviewblockSelfApprovalbooleanBlock approving your own requests?
ApprovalGateReviewenabledbooleanRequire approval
ApprovalGateReviewitemActions[ItemAction]Row actions
ApprovalGateReviewitemClickEventeventRow click
ApprovalGateReviewreviewSlotslotReview slot
ApprovalGateReviewtableLookstringReview queue table style
ApprovalGateReviewviewerRolestringViewer's role

std-audit-capture

event-interceptor audit log / audit trail. Use when a user voices that a record's changes must be tracked, logged, or auditable (audit trail, track changes, change history, who edited what, mutation log, record changes, log every edit, edit history, modification log, who did what when, accountability log). Listens for the generic EntityMutated sentinel (rename via traitOverrides.events to the real mutation event, e.g. ContactSaved) and persists an AuditEntry row capturing actor, action, entity type/id, before/after snapshots, and timestamp. captureEventTypes filters on @payload.data.kind, or on the delivered event's own name when the payload carries no kind (empty = capture all). Every entry also records where the change came from — the delivering event, the behavior and module that emitted it, and the scheduled job when a tick caused it — with no change to the upstream emitter. Compose with std-lifecycle to apply retention. Composable via extraTraits to interpose audit logging behind any mutating trait.

lolo
1 uses AuditCapture from "std/behaviors/std-audit-capture"

Entity: AuditEntry (persistent)

Traits

Traiteventsemits
AuditCaptureListenerEntityMutatedAuditRecorded

Config knobs

TraitKnobTypeLabel
AuditCaptureListenercaptureBeforeAfterbooleanStore before-and-after snapshots?
AuditCaptureListenercaptureEntityentityEntity to audit
AuditCaptureListenercaptureEventTypes[string]Event-kind filter
AuditCaptureListenerenabledbooleanTrack every change
AuditCaptureListenerexcludeFields[string]Skip fields

std-cache-aside

std-cache-aside as a Function

lolo
1 uses CacheAside from "std/behaviors/std-cache-aside"

Entity: CacheEntry (runtime)

Traits

Traiteventsemits
FetchButtonnonenone
InvalidateButtonnonenone
RefreshButtonnonenone
RetryButtonnonenone
CacheEntryCacheManagerFETCH, INVALIDATE, CACHED, REFRESHCacheEntryLoaded, CacheEntryLoadFailed, CacheEntryUpdated, CacheEntryUpdateFailed
InlineIconRender1nonenone
InlineTypographyRender2nonenone
InlineDividerRender3nonenone
InlineEmptyStateRender4nonenone
InlineIconRender5nonenone
InlineTypographyRender6nonenone
InlineStatusDotRender7nonenone
InlineDividerRender8nonenone
InlineIconRender9nonenone
InlineTypographyRender10nonenone
InlineBadgeRender11nonenone
InlineTypographyRender12nonenone
InlineIconRender13nonenone
InlineTypographyRender14nonenone
InlineTypographyRender15nonenone
InlineIconRender16nonenone
InlineTypographyRender17nonenone
InlineStatusDotRender18nonenone
InlineDividerRender19nonenone
InlineAlertRender20nonenone
InlineSpinnerRender21nonenone
InlineEmptyStateRender22nonenone

Config knobs

TraitKnobTypeLabel
FetchButtonactionunknown
FetchButtoniconunknown
FetchButtonlabelunknown
FetchButtonvariantunknown
InvalidateButtonactionunknown
InvalidateButtoniconunknown
InvalidateButtonlabelunknown
InvalidateButtonvariantunknown
RefreshButtonactionunknown
RefreshButtoniconunknown
RefreshButtonlabelunknown
RefreshButtonvariantunknown
RetryButtonactionunknown
RetryButtoniconunknown
RetryButtonlabelunknown
RetryButtonvariantunknown
CacheEntryCacheManageremptyLookstringEmpty-state look
CacheEntryCacheManagertableLookstringTable look
InlineIconRender1nameunknown
InlineTypographyRender2contentunknown
InlineTypographyRender2variantunknown
InlineEmptyStateRender4descriptionunknown
InlineEmptyStateRender4iconunknown
InlineEmptyStateRender4lookunknown
InlineEmptyStateRender4titleunknown
InlineIconRender5nameunknown
InlineTypographyRender6contentunknown
InlineTypographyRender6variantunknown
InlineStatusDotRender7labelunknown
InlineStatusDotRender7pulseunknown
InlineStatusDotRender7statusunknown
InlineIconRender9nameunknown
InlineTypographyRender10contentunknown
InlineTypographyRender10variantunknown
InlineBadgeRender11labelunknown
InlineTypographyRender12contentunknown
InlineTypographyRender12variantunknown
InlineIconRender13colorunknown
InlineIconRender13nameunknown
InlineTypographyRender14contentunknown
InlineTypographyRender14variantunknown
InlineTypographyRender15colorunknown
InlineTypographyRender15contentunknown
InlineTypographyRender15variantunknown
InlineIconRender16nameunknown
InlineTypographyRender17contentunknown
InlineTypographyRender17variantunknown
InlineStatusDotRender18labelunknown
InlineStatusDotRender18pulseunknown
InlineStatusDotRender18statusunknown
InlineAlertRender20messageunknown
InlineAlertRender20variantunknown
InlineEmptyStateRender22descriptionunknown
InlineEmptyStateRender22iconunknown
InlineEmptyStateRender22lookunknown
InlineEmptyStateRender22titleunknown

std-calendar-sync

two-way Google Calendar synchronization engine. PUSH: a 15-minute cron scan (and the user-addressable SYNC_NOW) walks targetEntity rows whose externalEventId marker is blank and creates a remote event per row through calendar.createEvent, reading the summary/start/end via the configured field mapping (titleField/startField/endField/durationMinutes fallback/locationField/descriptionField) — so ANY event-shaped host entity pushes, provided it declares the two marker columns externalEventId : string and syncedAt : number (the remindedAt precedent). PULL: CAL_REMOTE_CHANGED (delivered by the shared /api/hooks/google-calendar ingress from a calendar.watch channel) or the same cycle after a clean push lists remote events (incremental via the in-memory sync token; a restart falls back to a full window list) and upserts each into the atom's own canonical CalendarEvent store, matched by externalEventId — pulls land in the canonical store, NOT the arbitrary target, because persist keys are static in the language; bind calendar UI to CalendarEvent to surface remote events. Conflict detection (local-newer-than-remote) needs a local-modified marker convention and is a recorded gap, not a decorative state. Composes with std-notify-on-event via CAL_SYNCED / CAL_SYNC_FAILED.

lolo
1 uses CalendarSync from "std/behaviors/std-calendar-sync"

Entity: CalendarSyncRun (persistent)

Traits

Traiteventsemits
CalendarSyncSYNC_NOW, CAL_REMOTE_CHANGEDCAL_SYNCED, CAL_SYNC_FAILED, PUSH_ROWS_LOADED, CAL_EVENT_CREATED, PUSH_STEPPED, CAL_REMOTE_LISTED, PULL_TARGET_LOADED, PULL_STEPPED, PULL_NEXT

Config knobs

TraitKnobTypeLabel
CalendarSynccalendarIdstringCalendar id
CalendarSyncdescriptionFieldstringDescription field
CalendarSyncdurationFieldstringDuration field
CalendarSyncdurationMinutesnumberDuration (minutes)
CalendarSyncenabledbooleanSync with Google Calendar
CalendarSyncendFieldstringEnd field
CalendarSynclocationFieldstringLocation field
CalendarSyncstartFieldstringStart field
CalendarSynctargetEntityentityEntity to push
CalendarSynctitleFieldstringTitle field

std-cascade-on-delete

relational owns cascade. Listens for a parent-deleted sentinel (ParentDeleted — rename via traitOverrides.events to the consumer's actual parent-deleted event), then deletes every dependent row whose foreignKeyField points at the deleted parent — via a self-driving loop (delete the head of the matching set, re-fetch until none remain). Emits CascadeRowDeleted per row and CascadeCompleted when done.

lolo
1 uses CascadeOnDelete from "std/behaviors/std-cascade-on-delete"

Entity: CascadeLog (persistent)

Traits

Traiteventsemits
CascadeOnDeleteGateParentDeletedCascadeRowDeleted, CascadeCompleted, DepsLoaded, CascadeStepped, CascadeFailed

Config knobs

TraitKnobTypeLabel
CascadeOnDeleteGatedependentEntityentityDependent entity
CascadeOnDeleteGateenabledbooleanDelete related records too
CascadeOnDeleteGateforeignKeyFieldstringForeign-key field
CascadeOnDeleteGateparentEntityentityParent entity

std-circuit-breaker

std-circuit-breaker as a Function

lolo
1 uses CircuitBreaker from "std/behaviors/std-circuit-breaker"

Entity: ServiceNode (runtime)

Traits

Traiteventsemits
ShieldIconnonenone
AlertTriangleIconnonenone
ActivityIconnonenone
ServiceNodeLabelnonenone
ClosedStatusDotnonenone
OpenStatusDotnonenone
HalfOpenStatusDotnonenone
SuccessAlertnonenone
ErrorAlertnonenone
WarningAlertnonenone
FailuresStatnonenone
SuccessesStatnonenone
FailuresMeternonenone
ResetButtonnonenone
CircuitDividernonenone
StatsGridnonenone
ServiceNodeCircuitBreakerFAILURE, SUCCESS, TIMEOUT, RESETServiceNodeLoaded, ServiceNodeLoadFailed

Config knobs

TraitKnobTypeLabel
ShieldIconnameunknown
AlertTriangleIconnameunknown
ActivityIconnameunknown
ServiceNodeLabelcontentunknown
ServiceNodeLabelvariantunknown
ClosedStatusDotlabelunknown
ClosedStatusDotpulseunknown
ClosedStatusDotstatusunknown
OpenStatusDotlabelunknown
OpenStatusDotpulseunknown
OpenStatusDotstatusunknown
HalfOpenStatusDotlabelunknown
HalfOpenStatusDotpulseunknown
HalfOpenStatusDotstatusunknown
SuccessAlertmessageunknown
SuccessAlertvariantunknown
ErrorAlertmessageunknown
ErrorAlertvariantunknown
WarningAlertmessageunknown
WarningAlertvariantunknown
FailuresStatlabelunknown
FailuresStatlookunknown
FailuresStatvalueunknown
SuccessesStatlabelunknown
SuccessesStatlookunknown
SuccessesStatvalueunknown
FailuresMetermaxunknown
FailuresMeterminunknown
FailuresMetervalueunknown
ResetButtonactionunknown
ResetButtoniconunknown
ResetButtonlabelunknown
ResetButtonvariantunknown
StatsGridchildrenunknown
StatsGridcolsunknown
ServiceNodeCircuitBreakerfailureThresholdnumberFailure threshold
ServiceNodeCircuitBreakerstatLookstringStat display look

std-cooldown

ability/action cooldown primitive; START begins the countdown, READY fires when it expires.

lolo
1 uses Cooldown from "std/behaviors/std-cooldown"

Entity: CooldownRecord (runtime)

Traits

Traiteventsemits
CooldownSTARTCooldownReady, EXPIRE

Config knobs

TraitKnobTypeLabel
CooldowndefaultDurationMsnumberDefault cooldown duration (ms)

std-cross-reference

join-table primitive for N:M relationships. Listens for LinkRequested/UnlinkRequested/FETCH_LINKS_FOR and manages the junction collection (default CrossRefLink [persistent: cross_ref_links]). Rebind via linkedEntity={YourJunction} to your consumer junction; if your junction's id fields differ from leftId/rightId, override them with fields{} renames at the call site. A rebind target must supply leftId, rightId, createdAt, filteredLinks. Emits LinkCreated, LinkRemoved, LinksLoaded as external broadcasts for downstream consumers.

lolo
1 uses CrossReference from "std/behaviors/std-cross-reference"

Entity: CrossRefLink (persistent)

Traits

Traiteventsemits
CrossReferenceGateLinkRequested, UnlinkRequested, FETCH_LINKS_FORLinkCreated, LinkRemoved, LinksLoaded, LinksFetched, LinkOpFailed

std-data-erasure

GDPR Art. 17 right-to-be-forgotten queue. Tracks ErasureRequest rows through pending → grace → executed lifecycle with Cancel during grace. v1.0 ships the request lifecycle UI + knob set; auto-emit of ExecuteErasure after grace lands in v1.1 (loop-with-emit gap — docs/Almadar_Std_Factories.md). Target app/ atoms then own the actual delete or piiFields scrub via an ExecuteErasure listener.

lolo
1 uses DataErasure from "std/behaviors/std-data-erasure"

Entity: ErasureRequest (persistent)

Traits

Traiteventsemits
LoadingSpinnernonenone
ErrorSpinnernonenone
LoadingTextnonenone
Trash2Iconnonenone
ErasureRequestsTitlenonenone
CloseButtonnonenone
ErasureDividernonenone
ErrorAlertnonenone
ErasureWorkflowOPENCANCEL_ERASURE, CLOSE, ErasureLoaded, ErasureLoadFailed, ErasureSaved, ErasureSaveFailed, ExecuteErasure, ExecScanLoaded, ExecScanFailed, ExecStepped

Config knobs

TraitKnobTypeLabel
ErrorSpinnersizeunknown
LoadingTextcolorunknown
LoadingTextcontentunknown
LoadingTextvariantunknown
Trash2Iconnameunknown
ErasureRequestsTitlecontentunknown
ErasureRequestsTitlevariantunknown
CloseButtonactionunknown
CloseButtoniconunknown
CloseButtonlabelunknown
CloseButtonvariantunknown
ErrorAlertmessageunknown
ErrorAlertvariantunknown
ErasureWorkflowenabledbooleanAllow data erasure (GDPR)
ErasureWorkflowitemActions[ItemAction]Row actions
ErasureWorkflowreviewSlotslotReview slot
ErasureWorkflowtableLookstringErasure queue table style
ErasureWorkflowtargetEntitystringTarget entity
ErasureWorkflowviewerRolestringViewer's role

std-data-import

staged CSV import run, source-agnostic: upload → staged review → confirm → parse+map → handoff. UPLOAD_CSV opens a run and persists an ImportBatch row (status uploaded, fieldMappingJson recorded verbatim for provenance); the host's file UI parses the CSV and answers with STAGE_ROWS, one JSON string per raw row, which the atom bulk-persists into import_rows against the batch id and presents as a staged review (row/error counts + Confirm/Discard). CONFIRM_IMPORT marks the batch confirmed, emits IMPORT_CONFIRMED { batchId, sourceName, rowCount }, and fetches the batch's staged rows; on fetch success the atom parses each rowJson via json/parse, remaps keys through the batch's mappingJson, and emits IMPORT_ROWS_PARSED { batchId, rows, failed } — the persist half is the CONSUMER organism's: it listens for IMPORT_ROWS_PARSED and persists the mapped rows into its own target entity (cross-atom persist into a consumer's entity is not expressible from here). This is deliberately the CSV-file path: the atom never calls a source service — sourceName/fieldMappingJson/targetEntity are consumer configs, and any persist failure marks the batch row failed and fires IMPORT_FAILED, never a silent swallow. Compose with std-import for the file-picker menu.

lolo
1 uses DataImport from "std/behaviors/std-data-import"

Entity: ImportBatch (persistent)

Traits

Traiteventsemits
DataImportLifecycleUPLOAD_CSV, STAGE_ROWS, DISCARD_IMPORT, CONFIRM_IMPORT, RESETBATCH_CREATED, ROWS_STAGED, IMPORT_PERSIST_FAILED, IMPORT_CONFIRMED, IMPORT_ROWS_FETCHED, IMPORT_ROWS_PARSED, IMPORT_FAILED

Config knobs

TraitKnobTypeLabel
DataImportLifecyclefieldMappingJsonstringField mapping (JSON)
DataImportLifecyclesourceNamestringSource name
DataImportLifecycletargetEntitystringTarget entity

std-game-clock

fixed-timestep authoritative clock games compose to drive time; emits GameClockTicked every 100ms while running.

lolo
1 uses GameClock from "std/behaviors/std-game-clock"

Entity: GameClockRecord (runtime)

Traits

Traiteventsemits
GameClockPAUSE, RESUMEGameClockTicked

Config knobs

TraitKnobTypeLabel
GameClockautoStartbooleanAuto-start clock

std-global-search

cross-module federated search. Use when a user voices that one search box should query several modules at once (global search, search everything, unified search, cross-module search, federated search, search across records, omnisearch, one search box, aggregated results, grouped results). One SEARCH event fans out to every module key listed in the modules config (comma-separated, deterministic — no registry magic): the trait walks the parsed key list with an internal FAN_OUT_STEP sentinel and emits one scoped MODULE_SEARCH_REQUESTED { moduleKey, queryText, typeFilter, scopeJson } -> external per key, so modules respond in parallel rather than in sequence. Modules answer with SEARCH_RESULTS { moduleKey, resultsJson }; each answer appends a SearchResultGroup to the entity, so the merged view stays grouped by module. A module that answers twice is counted once, a keyless answer is filed under the answering module's name, and every group records which behavior answered it. Client/person/date/type filters ride scopeJson — the atom never interprets them. Every query persists as a SearchQuery row (recent/saved searches) when saveHistory is on. The input is the mapped search-input type rendered inline with event renamed to SEARCH (the std-geosearch idiom); its native {searchTerm}/{value} payloads are bridged via str/default, so programmatic SEARCH { queryText, typeFilter, scopeJson } emitters and the UI box drive the same arm.

lolo
1 uses GlobalSearch from "std/behaviors/std-global-search"

Entity: SearchQuery (persistent)

Traits

Traiteventsemits
GlobalSearchSEARCH_RESULTSSEARCH, MODULE_SEARCH_REQUESTED, GLOBAL_SEARCH_COMPLETED, QUERY_SAVED, QUERY_SAVE_FAILED, FAN_OUT_STEP
InlineTypographyRender1nonenone
InlineSpinnerRender2nonenone
InlineTypographyRender3nonenone
InlineTypographyRender4nonenone
InlineTypographyRender5nonenone

Config knobs

TraitKnobTypeLabel
GlobalSearchmodulesstringModules to search
GlobalSearchplaceholderstringSearch placeholder
GlobalSearchsaveHistorybooleanKeep recent searches
InlineTypographyRender1colorunknown
InlineTypographyRender1contentunknown
InlineTypographyRender1variantunknown
InlineTypographyRender3colorunknown
InlineTypographyRender3contentunknown
InlineTypographyRender3variantunknown
InlineTypographyRender4contentunknown
InlineTypographyRender4variantunknown
InlineTypographyRender5contentunknown
InlineTypographyRender5variantunknown

std-knowledge-loop

generic epistemic-loop / decision-gate machinery. Use when a user voices that a claim, hypothesis, or fix needs to be varied, predicted, falsified, independently checked, and calibrated before it is trusted (root-cause investigation, hypothesis testing, a fix that needs sign-off before it ships, a claim that needs a second opinion). The topology (vary -> compare -> hypothesize -> predict -> falsify -> verify -> generalize -> isolate & intervene -> compose -> calibrate -> select next target -> vary again) is fixed and never re-authored per domain. Each gate is announced: entering falsification emits FalsificationRequested, entering verification emits VerificationRequested, entering calibration emits CalibrationRequested (all carry the claim's title + candidateStructure). Who answers a gate is the consumer's call: with manualFalsification / manualVerification on (the default) the atom renders Survived/Failed and Checks-agree/Checks-disagree buttons and a person judges; a consumer that can compute the verdict sets the knob off, authors a sibling trait that listens for the *Requested event, does the domain check, and emits its result, then overrides listens {} at the call site to route that result into SURVIVED/FAILED or CHECKS_AGREE/CHECKS_DISAGREE — the when guard on that route IS the consumer's definition of what the gate means (e.g. ReproCheck.REPRO_RESULT -> SURVIVED when (>= ?passRate 0.95)). Calibration is enforced by the atom itself: a submitted numeric score is checked against reliabilityThreshold. On a claim clearing calibration, emits LoopConcluded (title, reliabilityScore) so a composing host can act on the validated result.

lolo
1 uses KnowledgeLoop from "std/behaviors/std-knowledge-loop"

Entity: KnowledgeClaim (runtime)

Traits

Traiteventsemits
LoopTitlenonenone
AwaitingFalsificationTextnonenone
AwaitingVerificationTextnonenone
LoopDividernonenone
SurvivedButtonnonenone
FailedButtonnonenone
ChecksAgreeButtonnonenone
ChecksDisagreeButtonnonenone
ChooseNextTargetButtonnonenone
KnowledgeLoopCHANGE_CONDITION, MEASURE_DIFFERENCE, FORM_GUESS, EXTRAPOLATE, SURVIVED, FAILED, CHECKS_AGREE, CHECKS_DISAGREE, STRIP_TO_ESSENTIALS, FIND_AND_CONTROL_CAUSE, COMBINE_WITH_TRUSTED, CONFIRM_SCORE, CANCEL_SCORE, CHOOSE_NEXT_TARGETFalsificationRequested, VerificationRequested, CalibrationRequested, LoopConcluded

Config knobs

TraitKnobTypeLabel
LoopTitlecontentunknown
LoopTitlevariantunknown
AwaitingFalsificationTextcolorunknown
AwaitingFalsificationTextcontentunknown
AwaitingFalsificationTextvariantunknown
AwaitingVerificationTextcolorunknown
AwaitingVerificationTextcontentunknown
AwaitingVerificationTextvariantunknown
SurvivedButtonactionunknown
SurvivedButtoniconunknown
SurvivedButtonlabelunknown
SurvivedButtonvariantunknown
FailedButtonactionunknown
FailedButtoniconunknown
FailedButtonlabelunknown
FailedButtonvariantunknown
ChecksAgreeButtonactionunknown
ChecksAgreeButtoniconunknown
ChecksAgreeButtonlabelunknown
ChecksAgreeButtonvariantunknown
ChecksDisagreeButtonactionunknown
ChecksDisagreeButtoniconunknown
ChecksDisagreeButtonlabelunknown
ChecksDisagreeButtonvariantunknown
ChooseNextTargetButtonactionunknown
ChooseNextTargetButtoniconunknown
ChooseNextTargetButtonlabelunknown
ChooseNextTargetButtonvariantunknown
KnowledgeLoopmanualFalsificationbooleanFalsification is judged by a person
KnowledgeLoopmanualVerificationbooleanVerification is judged by a person
KnowledgeLoopreliabilityThresholdnumberReliability threshold
KnowledgeLooprequireIndependentVerificationbooleanRequire independent verification

std-lifecycle

age-based status lifecycle for a target entity. A periodic tick scans the target for records in fromStatus whose dateField is older than ageDays, and transitions each one to toStatus — every matching record, via a self-driving scan loop (process the head of a filtered fetch, persist the status, re-fetch until the set drains). Compose onto any orbital and bind targetEntity + the status/date knobs.

lolo
1 uses Lifecycle from "std/behaviors/std-lifecycle"

Entity: LifecycleRunLog (persistent)

Traits

Traiteventsemits
LifecycleSchedulernoneLifecycleTransitioned, ScanRecordsLoaded, ScanFailed, LifecycleStepped

Config knobs

TraitKnobTypeLabel
LifecycleSchedulerageDaysnumberHow old (in days) before a record is transitioned?
LifecycleSchedulerdateFieldstringWhich date field measures the record's age?
LifecycleSchedulerdryRunbooleanRun in dry-run mode (no changes written)?
LifecycleSchedulerenabledbooleanAuto-archive old records
LifecycleSchedulerfromStatusstringWhich status triggers the age-out?
LifecycleSchedulertargetEntityentityTarget entity
LifecycleSchedulertoStatusstringWhat status should old records move to?

std-migration-job

one import run of external data into the host system, modeled as a persistent MigrationJob row with a lifecycle state machine: idle → fetching → mapping → reviewing → committing → done | failed. All source access goes through the migration service (call-service "migration" listDocuments / fetchDocument / commit) — the atom never talks to a source directly, and the host-injected service handler resolves credentials from the connectionRef knob (a reference, never the secret). Staging/mapping is host work (deterministic pipeline or agent): the atom fetches, the host stages and emits MIGRATION_STAGED with stats and, optionally, the staged units/skipped/validationErrors rows themselves — when the rows are supplied, reviewing renders an ImportPreviewTree so the user can see what will commit before approving. The user approves (MIGRATION_APPROVED) and only then does commit run. Terminal runs persist the job row for provenance. Rebind the entity to a host-owned job entity via linkedEntity; target, connectionRef and reviewSlot are config knobs.

lolo
1 uses MigrationJob from "std/behaviors/std-migration-job"

Entity: MigrationJob (persistent)

Traits

Traiteventsemits
MigrationJobLifecycleMIGRATION_START, FETCH_DOCUMENT, MIGRATION_STAGED, MIGRATION_DISCARDED, MIGRATION_APPROVED, MIGRATION_REJECTED, CLOSE, RESET, MIGRATION_RETRYDOCUMENTS_LISTED, DOCUMENT_FETCHED, COMMITTED, MIGRATION_CALL_FAILED, MIGRATION_FETCHED, MIGRATION_DOCUMENT, MIGRATION_REVIEW_READY, MIGRATION_COMPLETED, MIGRATION_FAILED

Config knobs

TraitKnobTypeLabel
MigrationJobLifecycleconnectionRefsecretConnection reference
MigrationJobLifecyclereviewSlotslotReview slot
MigrationJobLifecycletargetstringTarget entity

std-mod-queue

moderation queue for content review. Owns a ModQueueItem entity (one row per flagged target) and a single review trait that loads pending items, renders them in a data-grid with Approve / Reject / Escalate actions, and persists the reviewer's verdict back to the row.

lolo
1 uses ModQueue from "std/behaviors/std-mod-queue"

Entity: ModQueueItem (persistent)

Traits

Traiteventsemits
LoadingSpinnernonenone
ErrorSpinnernonenone
LoadingTextnonenone
ShieldAlertIconnonenone
ModQueueTitlenonenone
CloseButtonnonenone
ModQueueDividernonenone
ErrorAlertnonenone
ModQueueItemReviewOPENAPPROVE, REJECT, ESCALATE, CLOSE, ModQueueItemLoaded, ModQueueItemLoadFailed, ModQueueItemReviewed, ModQueueItemReviewFailed

Config knobs

TraitKnobTypeLabel
ErrorSpinnersizeunknown
LoadingTextcolorunknown
LoadingTextcontentunknown
LoadingTextvariantunknown
ShieldAlertIconnameunknown
ModQueueTitlecontentunknown
ModQueueTitlevariantunknown
CloseButtonactionunknown
CloseButtoniconunknown
CloseButtonlabelunknown
CloseButtonvariantunknown
ErrorAlertmessageunknown
ErrorAlertvariantunknown
ModQueueItemReviewautoEscalateThresholdnumberAuto-escalate at
ModQueueItemReviewenabledbooleanEnable moderation queue
ModQueueItemReviewitemActions[ItemAction]Row actions
ModQueueItemReviewreviewSlotslotReview slot
ModQueueItemReviewtableLookstringTable look
ModQueueItemReviewtitlestringSection title
ModQueueItemReviewviewerRolestringViewer's role

std-notification-center

per-user notification preferences, web-push subscriptions, and the digest drain for suppressed notifications. Owns the two owner-scoped stores std-notify-on-event consults at dispatch time: NotificationPreference rows (per event key: mode instant/digest/off, channel override, per-user quiet hours) and PushSubscription rows (captured via the browser/push-subscribe flow — the shared service worker + PushManager subscription, persisted as flat endpoint/p256dh/auth credentials). The DigestDrain trait is the delivery half of every suppression std-notify-on-event records: an hourly cron tick scans NotificationRecord audit rows left undispatched for digest/quiet-hours reasons and at least minAgeHours old, delivers each by email (the digest channel), and marks it dispatched — the reminder-scheduler self-driving scan loop verbatim. Compose alongside std-notify-on-event: the listener suppresses and records, this atom captures subscriptions, edits preferences, and drains.

lolo
1 uses NotificationCenter from "std/behaviors/std-notification-center"

Entity: NotificationPreference (persistent)

Traits

Traiteventsemits
PushSubscriberSUBSCRIBE_PUSHPUSH_SUBSCRIBED, PUSH_SUBSCRIBE_FAILED, PUSH_SAVED, PUSH_SAVE_FAILED
PreferenceEditorButtonSubscribenonenone
PreferenceEditorButtonDigestnonenone
PreferenceEditorOPEN_SUBSCRIBE, OPEN_DIGEST, SAVE_PREFERENCE, UPDATE_PREFERENCE, DELETE_PREFERENCEPREFERENCE_SAVED, PREFERENCE_DELETED, PREFERENCE_SAVE_FAILED
DigestDrainnoneDIGEST_ROWS_LOADED, DIGEST_ITEM_SENT, DIGEST_STEPPED, DIGEST_FAILED

Config knobs

TraitKnobTypeLabel
PreferenceEditorButtonSubscribeactionunknown
PreferenceEditorButtonSubscribelabelunknown
PreferenceEditorButtonDigestactionunknown
PreferenceEditorButtonDigestlabelunknown
DigestDraindigestEnabledbooleanDeliver digests
DigestDraindigestSubjectstringDigest email subject
DigestDrainminAgeHoursnumberMinimum age (hours)

std-notification-preferences

per-person notification preference store plus a consultable gate. Owns NotificationPreference rows (one per person + event key: channel override in_app/email/push/slack/sms/webhook, mode instant/digest/off, quiet-hours window 'HH:MM-HH:MM' such as 22:00-07:00). The PreferencesManage trait is standard CRUD over the store (list / create / update / delete, persisted, success/failure cascade arms): a data-grid browse plus ModalRecordModal create/edit forms whose SAVE carries the full row payload (std-list daisy-chain idiom). The PreferenceGate trait is the consult half other notify traits call: emit CHECK_PREFERENCE { personId, eventKey } and the gate fetches the matching row (a row whose eventKey is blank applies to every event) and answers PREFERENCE_RESOLVED { personId, eventKey, channel, mode, suppressed } — suppressed is true only when the row's quietHours window covers the current hour; mode 'digest' rides on the verdict for the caller to defer. Default policy: no matching row — or a failed lookup — resolves fail-open to { channel: in_app, mode: instant, suppressed: false }; the absence of a preference never silences a notification.

lolo
1 uses NotificationPreferences from "std/behaviors/std-notification-preferences"

Entity: NotificationPreference (persistent)

Traits

Traiteventsemits
PreferencesManageDO_CREATE, DO_UPDATE, RETRYCREATE, EDIT, DELETE, PreferencesLoaded, PreferencesLoadFailed, PreferenceSaved, PreferenceSaveFailed, PreferenceDeleted
PreferenceCreatenonenone
PreferenceEditnonenone
PreferenceGateCHECK_PREFERENCEPREFERENCE_RESOLVED, PREFERENCE_ROWS_LOADED, PREFERENCE_CHECK_FAILED

Config knobs

TraitKnobTypeLabel
PreferencesManageitemActions[ItemAction]Row actions
PreferencesManageitemClickEventeventRow click
PreferencesManagetableLookstringTable look
PreferencesManagetitlestringSection title
PreferencesManageviewerRolestringViewer's role
PreferenceCreatefieldsunknown
PreferenceCreateiconunknown
PreferenceCreatemodeunknown
PreferenceCreatetitleunknown
PreferenceEditfieldsunknown
PreferenceEditiconunknown
PreferenceEditmodeunknown
PreferenceEdittitleunknown
PreferenceGateeventKeystringEvent key

std-notify-on-event

cross-orbital wiring atom. Subscribes to events from another orbital (e.g. CheckoutOrbital emits OrderPlaced, OrderRecordOrbital reacts via this atom) and dispatches a notification. Use when one orbital needs to react to or be notified about events that happen in another orbital — the wiring goes through this atom's EventOccurred listener which the molecule renames via traitOverrides.events to the upstream event name. Dispatch gates on guardOp: eq (default) does string-equality on triggerStatus against the upstream event's status field; gt/lt/gte/lte instead numerically compare guardField (read from the event's data payload) against guardValue, for threshold-crossing asks such as low-stock alerts. Resolves recipient from recipients (first entry; multi-recipient fan-out is a future extension), falling back to fallbackRecipient when set, or @user.id otherwise. Skips dispatch when the recipient is in suppressionList. Delivery consults std-notification-center data before dispatching: per-person NotificationPreference rows (matched on personId = recipient and eventKey = this listener's eventKey, blank = all) can mute (mode: off), defer to the digest drain (mode: digest), override the channel, or impose per-user quiet hours (a 'HH:MM-HH:MM' window, blank = none); the atom-level quietStartHour/quietEndHour window and the frequencyCapPerWeek rolling cap (counted against dispatched NotificationRecord audit rows for the same recipient + channel) suppress likewise. Every suppression persists an honest audit row (dispatched: false with the reason in error: quiet-hours / digest-deferred / muted-by-preference / frequency-cap / no-push-subscription) which std-notification-center's digest cycle drains later. Channels: in-app emits the notify toast; email/sms/webhook dispatch through call-service (email.send / twilio.sendSMS / webhook.send); push looks up the recipient's PushSubscription row (owned by std-notification-center) and dispatches web-push via push.send (pushTitle falls back to template; pushDeepLink/pushIcon optional). The audit row's dispatched flag is honest — true only once the service call succeeds.

lolo
1 uses NotifyOnEvent from "std/behaviors/std-notify-on-event"

Entity: NotificationRecord (persistent)

Traits

Traiteventsemits
NotifyOnEventListenerEventOccurredNotificationDispatched, NOTIFY_PREFS_LOADED, NOTIFY_CAP_LOADED, NOTIFY_PUSH_SUBS, NOTIFY_EMAIL_SENT, NOTIFY_EMAIL_FAILED, NOTIFY_SMS_SENT, NOTIFY_SMS_FAILED, NOTIFY_WEBHOOK_SENT, NOTIFY_WEBHOOK_FAILED, NOTIFY_PUSH_SENT, NOTIFY_PUSH_FAILED, NOTIFY_LOOKUP_FAILED

Config knobs

TraitKnobTypeLabel
NotifyOnEventListenercoalescestringCollapse repeat notifications from one action?
NotifyOnEventListenercoalesceKeystringWhich field makes two events distinct?
NotifyOnEventListeneremailSubjectstringEmail subject
NotifyOnEventListenereventKeystringEvent key for preferences
NotifyOnEventListenerfallbackRecipientstringFallback recipient
NotifyOnEventListenerfrequencyCapPerWeeknumberFrequency cap (per week)
NotifyOnEventListenerguardFieldstringGuard field (numeric)
NotifyOnEventListenerguardOpstringGuard comparison
NotifyOnEventListenerguardValuenumberGuard value (numeric)
NotifyOnEventListenernotifyChannelstringChannel
NotifyOnEventListenerpushDeepLinkstringPush deep link
NotifyOnEventListenerpushIconstringPush icon
NotifyOnEventListenerpushTitlestringPush title
NotifyOnEventListenerquietEndHournumberQuiet hours end
NotifyOnEventListenerquietStartHournumberQuiet hours start
NotifyOnEventListenerrecipients[string]Recipients
NotifyOnEventListenerseveritystringSeverity
NotifyOnEventListenersuppressionList[string]Suppression list
NotifyOnEventListenertemplatestringMessage template
NotifyOnEventListenertriggerStatusstringTrigger status
NotifyOnEventListenerwebhookSecretstringWebhook secret
NotifyOnEventListenerwebhookUrlstringWebhook URL

std-page-open

opens a URL in a new, focused browser tab and reports the tab. Wire OPEN to something the person does (a button or a row action), so a page only ever opens because they asked for it. Needs a host with the page service (a browser extension).

lolo
1 uses PageOpen from "std/behaviors/std-page-open"

Entity: PageOpenRecord (runtime)

Traits

Traiteventsemits
PageOpenOPENTAB_OPENED, OPEN_CALL_FAILED, OPENED, OPEN_FAILED

Config knobs

TraitKnobTypeLabel
PageOpenstatusSlotslotStatus slot

std-page-search

runs one search on a site in a background tab: opens searchUrl with the query as the queryParam parameter, reads up to maxResults elements matching resultSelector (waiting up to waitMs for the results to appear), closes the tab, and reports RESULTS with the fields read from each. One search at a time: SEARCH is accepted again once RESULTS or SEARCH_FAILED is reported. It never clicks anything. Needs a host with the page service (a browser extension with access to the search pages).

lolo
1 uses PageSearch from "std/behaviors/std-page-search"

Entity: PageSearchRecord (runtime)

Traits

Traiteventsemits
PageSearchSEARCHTAB_OPENED, RESULTS_READ, SEARCH_CALL_FAILED, RESULTS, SEARCH_FAILED

Config knobs

TraitKnobTypeLabel
PageSearchfieldsMap<string,PageField>Fields
PageSearchmaxResultsnumberResults per search
PageSearchqueryParamstringQuery parameter
PageSearchresultSelectorstringResult selector
PageSearchresultsMatchstringResults pages
PageSearchsearchUrlstringSearch page
PageSearchstatusSlotslotStatus slot
PageSearchwaitMsnumberWait for results (ms)

std-page-treat

applies a declared visual treatment to one element of a browser tab (hide, blur, highlight, or label it with text) or restores it, and reports which element it treated. TREAT takes the tab and element id std-page-watch reports. The treatments are a fixed, declared set: no arbitrary styles or scripts. Needs a host with the page service (a browser extension).

lolo
1 uses PageTreat from "std/behaviors/std-page-treat"

Entity: PageTreatRecord (runtime)

Traits

Traiteventsemits
PageTreatTREATAPPLIED, APPLY_FAILED, TREATED, TREAT_FAILED

Config knobs

TraitKnobTypeLabel
PageTreatstatusSlotslotStatus slot

std-page-watch

watches every browser tab whose URL matches match for elements matching itemSelector, and reports each element once as ITEM with the fields read from it, now and as the page changes. Needs a host with the page service (a browser extension, which asks for access to exactly the match pages). Each item carries its tab and element id; compose std-page-treat to hide, blur, highlight or label it.

lolo
1 uses PageWatch from "std/behaviors/std-page-watch"

Entity: PageWatchRecord (runtime)

Traits

Traiteventsemits
PageWatchITEM_FOUNDWATCHING, WATCH_FAILED, ITEM

Config knobs

TraitKnobTypeLabel
PageWatchfieldsMap<string,PageField>Fields
PageWatchitemEventeventItem input
PageWatchitemSelectorstringItem selector
PageWatchmatchstringPages
PageWatchstatusSlotslotStatus slot

std-permission-matrix

role × module permission grant table / capability matrix admin surface. Use when a user voices that permissions must be managed per role and module (permission matrix, role permissions, capability matrix, permission grants, access matrix, who can see finance, hide margins, module-level permissions, admin permission screen, grant management, finance visibility by role, restrict modules by role). Persists PermissionGrant rows (workspaceId + role + module + capability flags canReadFinance / canSeeOthersHours / canSeeMargins) with full CRUD on an admin page mounted at /admin/permissions — create/edit forms are the std-modal ModalRecordModal substrate (the corpus's two-trait CRUD shape, mirroring std-list), persists live in a sibling coordinator trait, and adminRoles is ENFORCED at the persist boundary (a viewer whose role is not listed cannot fire a write, from the button or from the bus). Ships a query trait other traits consult event-wise: CHECK_GRANT { role, module } fetches the matching grant(s) and re-emits GRANT_RESOLVED { role, module, canReadFinance, canSeeOthersHours, canSeeMargins, found }. Grant SURFACE only — entity-layer @read/@update gate integration is a recorded core gap (gates are pure @entity/@user S-expressions and cannot consult another entity's rows), so enforcement stays with the consumer until that core lands.

lolo
1 uses PermissionMatrix from "std/behaviors/std-permission-matrix"

Entity: PermissionGrant (persistent)

Traits

Traiteventsemits
LoadingSpinnernonenone
ErrorSpinnernonenone
LoadingTextnonenone
ShieldCheckIconnonenone
PermissionMatrixTitlenonenone
GrantDividernonenone
ErrorAlertnonenone
PermissionMatrixAdminnoneNEW, EDIT, DELETE, PermissionGrantLoaded, PermissionGrantLoadFailed
PermissionGrantCreatenonenone
PermissionGrantEditnonenone
PermissionGrantPersistorDO_CREATE, DO_UPDATE, DO_DELETEPermissionGrantSaved, PermissionGrantSaveFailed, PermissionGrantDeleted, PermissionGrantDeleteFailed
PermissionGrantQueryCHECK_GRANTGRANT_RESOLVED, GrantCheckLoaded, GrantCheckFailed

Config knobs

TraitKnobTypeLabel
ErrorSpinnersizeunknown
LoadingTextcolorunknown
LoadingTextcontentunknown
LoadingTextvariantunknown
ShieldCheckIconnameunknown
PermissionMatrixTitlecontentunknown
PermissionMatrixTitlevariantunknown
ErrorAlertmessageunknown
ErrorAlertvariantunknown
PermissionMatrixAdminitemActions[ItemAction]Row actions
PermissionMatrixAdminitemClickEventeventRow click
PermissionMatrixAdminviewerRolestringViewer's role
PermissionGrantCreatefieldsunknown
PermissionGrantCreateiconunknown
PermissionGrantCreatemodeunknown
PermissionGrantCreatetitleunknown
PermissionGrantEditfieldsunknown
PermissionGrantEditiconunknown
PermissionGrantEditmodeunknown
PermissionGrantEdittitleunknown
PermissionGrantPersistoradminRoles[string]Who can manage grants?
PermissionGrantQueryenabledbooleanAnswer permission lookups

std-rate-limiter

std-rate-limiter as a Function

lolo
1 uses RateLimiter from "std/behaviors/std-rate-limiter"

Entity: RateBucket (runtime)

Traits

Traiteventsemits
ShieldIconnonenone
RateBucketTitlenonenone
OpenStatusDotnonenone
ThrottledStatusDotnonenone
RateLimitAlertnonenone
RequestsStatnonenone
WindowStatnonenone
CountMeternonenone
CountProgressBarnonenone
RequestButtonnonenone
ResetButtonnonenone
ResetPrimaryButtonnonenone
RateBucketDividernonenone
StatsGridnonenone
RateBucketRateLimiterREQUEST, THROTTLE, RESET, CONFIGUREWINDOW_ELAPSED

Config knobs

TraitKnobTypeLabel
ShieldIconnameunknown
RateBucketTitlecontentunknown
RateBucketTitlevariantunknown
OpenStatusDotlabelunknown
OpenStatusDotpulseunknown
OpenStatusDotstatusunknown
ThrottledStatusDotlabelunknown
ThrottledStatusDotpulseunknown
ThrottledStatusDotstatusunknown
RateLimitAlertmessageunknown
RateLimitAlertvariantunknown
RequestsStatlabelunknown
RequestsStatlookunknown
RequestsStatvalueunknown
WindowStatlabelunknown
WindowStatlookunknown
WindowStatvalueunknown
CountMetermaxunknown
CountMeterminunknown
CountMetervalueunknown
CountProgressBarmaxunknown
CountProgressBarshowPercentageunknown
CountProgressBarvalueunknown
RequestButtonactionunknown
RequestButtoniconunknown
RequestButtonlabelunknown
RequestButtonvariantunknown
ResetButtonactionunknown
ResetButtoniconunknown
ResetButtonlabelunknown
ResetButtonvariantunknown
ResetPrimaryButtonactionunknown
ResetPrimaryButtoniconunknown
ResetPrimaryButtonlabelunknown
ResetPrimaryButtonvariantunknown
StatsGridchildrenunknown
StatsGridcolsunknown
RateBucketRateLimiterenabledbooleanEnabled
RateBucketRateLimiterrequestsPerMinutenumberRequests per minute
RateBucketRateLimiterstatLookstringStat display look

std-reminder-scheduler

deadline reminders for a target entity. A periodic tick scans the target for records whose dateField deadline (a ms-epoch number or an ISO datetime string) is within offsetHours of now and that have not been reminded yet, and emits ReminderDue for each — every matching record, via a self-driving scan loop. direction picks which side of now the scan matches: 'future' (default) fires for deadlines up to offsetHours ahead; 'past' fires once a record's date is at least offsetHours behind now. Marks each record remindedAt so it isn't reminded twice — and only when the record actually matched the scan, so records outside the window stay eligible for later passes. Compose alongside std-notify-on-event to deliver the reminder.

lolo
1 uses ReminderScheduler from "std/behaviors/std-reminder-scheduler"

Entity: ReminderRunLog (persistent)

Traits

Traiteventsemits
ReminderSchedulernoneReminderDue, ScanRecordsLoaded, ScanFailed, ReminderStepped

Config knobs

TraitKnobTypeLabel
ReminderSchedulerdateFieldstringWhich date field is the deadline?
ReminderSchedulerdirectionstringScan which side of now?
ReminderSchedulerenabledbooleanSend deadline reminders
ReminderScheduleroffsetHoursnumberHow many hours before the deadline to remind?
ReminderSchedulerseveritystringHow urgent are the reminders?
ReminderSchedulertargetEntityentityTarget entity
ReminderSchedulertemplatestringWhat should the reminder message say?

std-review-cycle

revise-and-resubmit review workflow (document review, pull-request review, design review, editorial review, submission review, send back for changes, request changes, resubmit, review rounds, four-eyes approval). A record moves draft → in review → changes requested → in review → … → approved. One SUBMIT event serves both the first submission and every resubmission; the atom counts review rounds and marks resubmissions on the emitted ReviewRequested. Every move writes a ReviewEvent history row stamped with the states it left and entered. requireSeparateApproval enforces four-eyes review: an approval raised in the same action that submitted the record (an auto-responding rule or bot) is rejected. Headless — the host renders the badge and buttons and routes its actions to SUBMIT / REQUEST_CHANGES / APPROVE.

lolo
1 uses ReviewCycle from "std/behaviors/std-review-cycle"

Entity: ReviewItem (persistent)

Traits

Traiteventsemits
ReviewCycleReviewSubmitted, ReviewChangesRequested, ReviewApprovedReviewLogged, ReviewLogFailed, ReviewRequested, ReviewDecided

Config knobs

TraitKnobTypeLabel
ReviewCycleenabledbooleanRun the review workflow?
ReviewCyclerequireSeparateApprovalbooleanRequire approval to be a separate action?

std-row-access-control

row-level access control gate / ownership filter / role-based row visibility. Use when a user voices that only certain users should see or edit certain records (only the owner can edit, private to owner, owner-only visibility, only see your own records, role-based visibility, admin-only access, visible to admins only, restricted to role, permission gate, ownership scoping, hide from other users, only show mine). Listens for RowsLoaded (rename via traitOverrides.events to the consumer's load event), filters @payload.data by @user.id (when ownerField is set) and/or @user.role (when visibleRoles is non-empty), re-emits RowsFiltered for downstream consumers (rename to wire into the UI atom's listen). Composable via extraTraits to interpose between a data fetch and a list/grid UI.

lolo
1 uses RowAccessControl from "std/behaviors/std-row-access-control"

Entity: RowAccessGateView (runtime)

Traits

Traiteventsemits
RowAccessGateRowsLoadedRowsFiltered

Config knobs

TraitKnobTypeLabel
RowAccessGateenabledbooleanRestrict who sees records
RowAccessGateownerFieldstringOwner field
RowAccessGatevisibleRoles[string]Allowed roles

std-status-lifecycle

the host renders the badge and buttons.

lolo
1 uses StatusLifecycle from "std/behaviors/std-status-lifecycle"

Entity: StatusRecord (persistent)

Traits

Traiteventsemits
StatusMachineChangeStatusRequestedStatusChanged, StatusPersisted, StatusChangeFailed

Config knobs

TraitKnobTypeLabel
StatusMachineenabledbooleanEnforce status lifecycle rules?
StatusMachinestates[string]What are the possible statuses?
StatusMachinestatusFieldstringWhich field holds the status?
StatusMachinetargetEntityentityTarget entity
StatusMachinetransitions[TransitionSpec]Which status moves are allowed?

organisms

std-status-lifecycle-control

infra molecule pairing std-status-lifecycle's StatusMachine, which deliberately surfaces no UI of its own. Pure presentational: shows the current status and one button per legal next move (config.transitions filtered on config.currentStatus), emitting ChangeStatusRequested with the picked move's id/from/to on click. Driven entirely by config (currentStatus/recordId/transitions) rather than a bound entity, so a host embeds it inline at the record it's viewing (currentStatus={@entity.status} recordId={@entity.id} transitions matching the paired StatusMachine's own config.transitions) and points that StatusMachine's listens at this trait's emit (<Composer>.ChangeStatusRequested -> ChangeStatusRequested) instead of at a dead declared-only event.

lolo
1 uses StatusLifecycleControl from "std/behaviors/std-status-lifecycle-control"

Entity: StatusControlItem (runtime)

Traits

Traiteventsemits
StatusLifecycleControlnoneChangeStatusRequested, TRANSITION_REQUESTED
InlineBadgeRender1nonenone

Config knobs

TraitKnobTypeLabel
StatusLifecycleControlcurrentStatusstringCurrent status
StatusLifecycleControlrecordIdstringRecord id
StatusLifecycleControltransitions[TransitionSpec]Which status moves are allowed?
InlineBadgeRender1amountnumberAmount
InlineBadgeRender1ariaBusybooleanAria-busy
InlineBadgeRender1ariaCurrentstringAria-current
InlineBadgeRender1ariaDescribedbystringAria-describedby
InlineBadgeRender1ariaExpandedbooleanAria-expanded
InlineBadgeRender1ariaHiddenbooleanAria-hidden
InlineBadgeRender1ariaLabelstringAria-label
InlineBadgeRender1ariaLabelledbystringAria-labelledby
InlineBadgeRender1ariaLivestringAria-live
InlineBadgeRender1ariaPressedstringAria-pressed
InlineBadgeRender1ariaSelectedbooleanAria-selected
InlineBadgeRender1classNamestringClass Name
InlineBadgeRender1dirstringDir
InlineBadgeRender1enterstringEnter
InlineBadgeRender1enterDelaynumberEnter Delay
InlineBadgeRender1iconiconIcon
InlineBadgeRender1iconAssetBadgeIconAssetIcon Asset
InlineBadgeRender1labelscalarLabel
InlineBadgeRender1langstringLang
InlineBadgeRender1onRemoveeventOn Remove
InlineBadgeRender1removeLabelstringRemove Label
InlineBadgeRender1rolestringRole
InlineBadgeRender1sizestringSize
InlineBadgeRender1skeletonstringSkeleton
InlineBadgeRender1tabIndexnumberTab Index
InlineBadgeRender1variantstringVariant
Orb

The language where the rule is the program.

© 2026 Almadar. Ljubljana, Slovenia.