Skip to content

docs(adr-0078): the completeness gate — Zod-valid-but-inert metadata must fail loudly at author time#2426

Merged
os-zhuang merged 1 commit into
mainfrom
docs/adr-0078-functional-completeness
Jun 28, 2026
Merged

docs(adr-0078): the completeness gate — Zod-valid-but-inert metadata must fail loudly at author time#2426
os-zhuang merged 1 commit into
mainfrom
docs/adr-0078-functional-completeness

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

What

ADR-0078 + its evidence doc. Establishes the completeness gate: a metadata instance that is Zod-valid but functionally incomplete (and therefore silently does nothing at runtime) must fail loudly at author time, enforced uniformly across every authoring surface — not just the cloud AI-build path.

  • docs/adr/0078-no-silently-inert-metadata.md — the decision
  • docs/audits/2026-06-metadata-functional-completeness.md — the evidence (5-angle audit, deduped + confidence-tiered)

Why

Surfaced by cloud#687: an AI-built summary field shipped as a dead {type:'summary'} shell, the dependent "occupancy rate" formula was forever 0, and the agent reported it done. A 5-angle audit showed this is a class, not a one-off.

It sits in a precise seam in the existing 3-gate chain:

Gate Question Misses a bare summary because
ADR-0049 liveness does any code read property P? summaryOperations is live (per-property, blind to a per-instance omission)
ADR-0054 prove-it-runs does a correct instance run? proves a complete summary computes; never asserts an incomplete one is rejected
ADR-0038 / gate-1 lint is the metadata valid? {type:'summary'} is valid; completeness coverage is incomplete and cloud-only

@objectstack/lint (framework) does expressions/widgets/SDUI but no field/view/action completeness; formula_without_expression exists only in cloud graph-lint. So os build/os validate/MCP/hand authors get none of it — exactly the wrong shape when AI authors across many surfaces.

Decision (in brief)

  1. Extend ADR-0049's trichotomy from property to instance: a config whose omission makes an instance silently inert must be completeness-enforced, [EXPERIMENTAL — not enforced], or gracefully-optional — never parsed-and-silently-inert.
  2. One shared per-type predicate in @objectstack/spec (sibling of isIncoherentAggregate), consumed by both @objectstack/lint and cloud graph-lint → kills the path asymmetry.
  3. Fix the cloud root cause: materialization must spread-not-allow-list (and the blueprint field shape must represent type-specific config) so a correct authoring can't be silently stripped.
  4. Optional runtime loud-not-silent diagnostic (the only authoring-tool-agnostic layer); no hard Zod refine (back-compat).
  5. Ratchet, not retrofit — verified Tier-A shapes now; the long tail gated on a verification pass.

Sibling to ADR-0077 (surface-routing traps) — same "loud-not-silent, AI-is-the-author" family, orthogonal axis.

Discipline note

The audit's scariest candidate — a "sharing rule fails open and shares every record" security claim — collapsed on a three-file read (condition is required; ExpressionInputSchema rejects empty; the match-all branch is gated per ADR-0049). The audit yields candidates, not bugs; each becomes a rule only after verification. That lesson is baked into the ratchet.

Status

Proposed — decision record for review, no code in this PR. cloud#687 already shipped the first instance (summary/formula rules); Phase 1 re-homes them onto the shared predicate.

🤖 Generated with Claude Code

…must fail loudly at author time, uniformly across surfaces

Surfaced by cloud#687 (an AI-built `summary` shipped as a dead `{type:'summary'}`
shell; the dependent "occupancy rate" was forever 0 while the agent reported it
done) plus a 5-angle functional-completeness audit.

Positions the decision precisely in the existing 3-gate chain: ADR-0049 closes
dead *properties* (per-property liveness), ADR-0054 closes *unproven* liveness
(integration), ADR-0077 closes *surface-routing* silent traps. The seam between
them — a Zod-valid *instance* that omits a sibling config its consumer needs and
silently no-ops (bare summary, action without `locations`, lookup without
`reference`, calendar without a date field) — is uncaught, and what coverage
exists lives ONLY in cloud graph-lint (framework `@objectstack/lint` has no
field/view/action completeness; `formula_without_expression` is cloud-only), so
`os build`/`os validate`/MCP/hand authors get none of it.

Decision (extends ADR-0049's trichotomy from property to instance): a config
whose omission makes an instance silently inert must be completeness-enforced,
marked `[EXPERIMENTAL — not enforced]`, or genuinely-graceful — never parsed-
and-silently-inert. The check is ONE shared per-type predicate in
`@objectstack/spec` (sibling of `isIncoherentAggregate`), consumed by BOTH
`@objectstack/lint` and cloud graph-lint — killing the path asymmetry. Plus the
cloud root cause: materialization must spread-not-allow-list so a correct
authoring isn't stripped. Ratchet, not retrofit (ADR-0054 idiom).

Includes the audit evidence doc with the deduped, confidence-tiered catalog and
a worked correction: the audit's scariest candidate (a "sharing rule fails open"
security claim) collapsed on a three-file read — the audit yields candidates,
not bugs; each becomes a rule only after verification.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 28, 2026 11:15am

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation labels Jun 28, 2026
@os-zhuang
os-zhuang merged commit 510f2f1 into main Jun 28, 2026
15 checks passed
@os-zhuang
os-zhuang deleted the docs/adr-0078-functional-completeness branch June 28, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant