You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
spec: the SLI successCriteria and composite trace-sampling condition CEL predicates are authorable, published and documented while nothing evaluates them — ADR-0049 enforce-or-remove, ungoverned by the liveness ledger #18118
Found while classifying the five positions of #17630 (that card is not addressed by this one; it widens discovery and writes ledger rows, and deliberately changes no behaviour). Filed by the os-dev seat, session session_01TbSMtGzMrtPwh925wDEZd5. No assignee; domain:*, type and priority are triage's.
Two authorable, published, documented expression slots accept a CEL predicate and nothing anywhere evaluates it. An author — or an AI author reading the generated reference page — writes a success criterion or a sampling condition, it parses, it registers, it is served back, and it has no effect. Nothing distinguishes that from a predicate that ran and answered.
Both are on the authorable surface (packages/spec/authorable-surface/system.json) and both are published as author-facing reference pages (content/docs/references/system/metrics.mdx, content/docs/references/system/tracing.mdx). The metrics one is additionally advertised as CEL in a shipped skill: skills/objectstack-formula/SKILL.md:398 lists audit / metrics / tracing with condition / successCriteria as structured | cel.
Measurement — zero consumers
Identity scan over the whole tree at a26a114d7. Every hit for successCriteria, ServiceLevelIndicatorSchema and TraceSamplingConfigSchema outside packages/spec/src is a generated artefact or prose:
Inside packages/spec/src the only readers are the two schemas' own unit tests (system/metrics.test.ts). No service, plugin, runtime or CLI path reads either key.
Why neither existing guard catches it
The liveness ledger does not govern these types.packages/spec/liveness/ is keyed on BUILTIN_METADATA_TYPE_SCHEMAS (its own README states this), and there is no metrics.json / tracing.json — ServiceLevelIndicatorSchema and TraceSamplingConfigSchema are not registered authorable metadata types, so the enforce-or-remove ratchet never asks about their properties. pnpm check:liveness is green and says nothing about them.
ADR-0049 enforce-or-remove, on two keys that are now classified but not disposed of. The triage ruling on #17630 (comment 5657520516) explicitly reserved this as a separate decision rather than folding it into the classification:
Whether either key should instead be RETIRED under ADR-0049 enforce-or-remove is a separate decision on its own card
Two dispositions, and picking one is the decision this card needs:
Wire an evaluator, which makes the declaration true and moves the ledger row off unevaluated.
⛔ Not in scope for this card as filed: changing the ledger row. That row is honest about what is there today, and it has to stay honest until one of the two dispositions lands.
⚠️ Note for whoever takes it: the structured (non-expression) arm of each union is a different question and is NOT part of this finding. successCriteria's {threshold, operator, percentile} arm and condition's z.record arm are equally unread by any runtime, but they carry no dialect and are outside the expression ledger's remit — measure them before assuming this card covers them.
Back-links: #17630 (the discovery half), #16320 (the cron family retired under the same ADR), ADR-0049, ADR-0058 D7.
Found while classifying the five positions of #17630 (that card is not addressed by this one; it widens discovery and writes ledger rows, and deliberately changes no behaviour). Filed by the
os-devseat, sessionsession_01TbSMtGzMrtPwh925wDEZd5. No assignee;domain:*, type and priority are triage's.Measured on
origin/maina26a114.The trap
Two authorable, published, documented expression slots accept a CEL predicate and nothing anywhere evaluates it. An author — or an AI author reading the generated reference page — writes a success criterion or a sampling condition, it parses, it registers, it is served back, and it has no effect. Nothing distinguishes that from a predicate that ran and answered.
packages/spec/src/system/metrics.zod.tsServiceLevelIndicatorSchema.successCriteriaz.union([{threshold, operator, percentile}, ExpressionInputSchema])packages/spec/src/system/tracing.zod.tsTraceSamplingConfigSchema.composite[].conditionz.union([z.record(z.string(), z.unknown()), ExpressionInputSchema])Both are on the authorable surface (
packages/spec/authorable-surface/system.json) and both are published as author-facing reference pages (content/docs/references/system/metrics.mdx,content/docs/references/system/tracing.mdx). Themetricsone is additionally advertised as CEL in a shipped skill:skills/objectstack-formula/SKILL.md:398listsaudit/metrics/tracingwithcondition/successCriteriaasstructured | cel.Measurement — zero consumers
Identity scan over the whole tree at
a26a114d7. Every hit forsuccessCriteria,ServiceLevelIndicatorSchemaandTraceSamplingConfigSchemaoutsidepackages/spec/srcis a generated artefact or prose:Inside
packages/spec/srcthe only readers are the two schemas' own unit tests (system/metrics.test.ts). No service, plugin, runtime or CLI path reads either key.Why neither existing guard catches it
packages/spec/liveness/is keyed onBUILTIN_METADATA_TYPE_SCHEMAS(its own README states this), and there is nometrics.json/tracing.json—ServiceLevelIndicatorSchemaandTraceSamplingConfigSchemaare not registered authorable metadata types, so the enforce-or-remove ratchet never asks about their properties.pnpm check:livenessis green and says nothing about them.unevaluated/ PARSE-ONLY row,cel-declared-unwired-observability. That row RECORDS the absence; it does not resolve it, and its own note says so.What this card is for
ADR-0049 enforce-or-remove, on two keys that are now classified but not disposed of. The triage ruling on #17630 (comment 5657520516) explicitly reserved this as a separate decision rather than folding it into the classification:
Two dispositions, and picking one is the decision this card needs:
spec-property-retirementplaybook: tombstone or strict removal, the changeset with its FROM/TO mapping, the ADR-0087 disposition, the generated baselines). The precedent is thecron-declared-unwiredfamily, retired outright under the same ADR at spec: retire the seven cron-typed positions nothing reads — export schedules,ScheduleState.cronExpression,DataSyncConfig.schedule,CacheWarmup.schedule, backup/DR schedules — under ADR-0049 (#15954 ruling, option A per family) #16320 after the same measurement.unevaluated.⛔ Not in scope for this card as filed: changing the ledger row. That row is honest about what is there today, and it has to stay honest until one of the two dispositions lands.
successCriteria's{threshold, operator, percentile}arm andcondition'sz.recordarm are equally unread by any runtime, but they carry no dialect and are outside the expression ledger's remit — measure them before assuming this card covers them.Back-links: #17630 (the discovery half), #16320 (the cron family retired under the same ADR), ADR-0049, ADR-0058 D7.