Skip to content

feat(spec,verify): prove-it-runs proof field + ratchet, binding 4 high-risk classes (ADR-0054 #1 + Phase 2) - #2045

Merged
os-zhuang merged 4 commits into
mainfrom
claude/lucid-gauss-t7dd3z
Jun 19, 2026
Merged

os-zhuang merged 4 commits into
mainfrom
claude/lucid-gauss-t7dd3z

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Jun 19, 2026 •

Copy link
Copy Markdown
Contributor

What & why

ADR-0054 follow-up (1) + Phase 2: define the authoritative high-risk-class list and add the proof field + ratchet to the spec liveness gate, then bind the high-risk classes — including new runtime proofs/bindings for flow nodes and analytics.

Until now, a live classification in the liveness ledger meant only a static pointer to a consumer — proof that something reads the property. That is necessary but not sufficient: a property can be live at every layer yet broken end-to-end (the break lives in the engine↔driver↔service↔HTTP integration — #2018, the rating/slider/toggle fidelity leak). ADR-0054 adds the third leg — prove-it-runs: for high-risk authorable classes, live must carry a proof (a @objectstack/dogfood test that authors the property against the real in-process stack and asserts the runtime outcome).

The earlier ADR-0054 follow-ups are already merged: field-fidelity fix + field-zoo (#2025/#2022), tz-bucketing proof (#2018), the @objectstack/verify engine (#2041), and the #1994 RLS seed + multi-user harness (#2024/#2032). This adds the missing keystone (the ratchet) and binds four classes.

Design (the proof contract)

  • proof = "<repo-relative-file>#<proof-id>". The dogfood test self-declares the id with a greppable // @proof: <id> tag near its top.
  • Validation is STATIC — the gate checks the file exists and declares the tag; it never runs the test (that's the dogfood gate's job), keeping the liveness gate seconds-cheap (ADR §4). A greppable tag (not a test title) is deliberate: field-zoo titles are generated in a loop.
  • Bidirectional integrity. A bound live entry must carry a valid proof of its own class. The reverse check flags any @proof: tag under packages/dogfood/test/** not registered in proof-registry.mts (warning).
  • Gate also triggers on packages/dogfood/**, so deleting/renaming a proof re-runs the check and a dangling reference is caught.

The ratchet — four classes bound (ADR §3)

A class is CI-enforced only once it has both a runtime proof and a governed ledger entry to carry it.

High-risk class Bound? Ledger binding Proof
Field types ✅ enforced field.type field-zoo-roundtrip#field-type-roundtrip
RLS / sharing ✅ enforced permission.rowLevelSecurity.using rls-fixture#rls-by-id-write
Flow nodes ✅ enforced flow.nodes.type flow-node#flow-node-execution (new proof)
Analytics dims/measures ✅ enforced dataset.dimensions.dateGranularity analytics-timezone#analytics-tz-bucketing (newly bound)
Form layout/section/widget ⛔ pending — none yet (form surface not governed)

Phase 2 — new this PR

Flow-node runtime proof. Flow execution wasn't reachable through the harness (bootStack registered no automation service). Mirroring how the RLS proof first needed a multi-user harness capability:

  • @objectstack/verify: bootStack gains an opt-in automation flag that registers @objectstack/service-automation; the app's flows are then pulled from the registry and their nodes execute. Default off — standard boot stays lean.
  • dogfood proof: a self-contained fixture (one object + one autolaunched flow whose update_record node stamps a record) triggers the flow over HTTP and asserts both directions — the targeted record IS stamped (node executed) and a bystander is not (the input variable wired into the node's filter, not a blanket update).

Govern dataset + bind analytics. The analytics proof existed (#2018) but its surface wasn't governed. This adds liveness/dataset.json (all 19 authorable props classified with file:line evidence from a consumer audit; 26 live, 1 dead) and binds dataset.dimensions.dateGranularity to the tz-bucketing proof.

Verification (all local, green)

  • pnpm --filter @objectstack/spec check:liveness → green; 11 governed types; reports the 4 bound classes.
  • Red paths confirmed: dangling proof tag → fail; bound live with no proof → fail; orphan tag → warning.
  • 17 unit + wiring tests (proof-registry.test.ts).
  • Flow-node proof runs green; analytics tz proof runs green; full dogfood suite 59/59.

🤖 Generated with Claude Code

…(ADR-0054 #1)

ADR-0054 follow-up (1): the liveness ledger's `live` meant only a static
consumer pointer — necessary but not sufficient, since a property can be live at
every layer yet broken end-to-end. This adds the third leg: high-risk authorable
properties must carry a `proof` (a dogfood test reference) that asserts the
runtime outcome.

- proof-registry.mts: the authoritative high-risk-class list (field types,
  analytics, RLS, flow nodes, form widgets) + which classes the ratchet enforces
  this phase. Field types and RLS are bound (matrix exists AND surface governed);
  analytics/flow/form are listed-but-blocked with honest reasons (their surface
  isn't governed yet / no proof yet — Phase 2).
- check-liveness.mts: a bound `live` entry must carry a valid `proof` of its own
  class. Validation is STATIC (file exists + declares the `@proof: <id>` tag) so
  the gate stays seconds-cheap; running the proof remains the dogfood gate's job.
  Reverse check flags unregistered `@proof:` tags.
- Ledger: field.type → field-zoo proof; permission.rowLevelSecurity.using →
  #1994 RLS proof. Dogfood proofs self-declare their `@proof:` tag.
- Gate now also triggers on packages/dogfood/** so deleting/renaming a proof
  re-runs the check and the dangling reference is caught.
- 15 unit + wiring tests; README documents the contract and ratchet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
@vercel

vercel Bot commented Jun 19, 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 19, 2026 10:33am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd tests tooling size/l labels Jun 19, 2026
@github-actions

github-actions Bot commented Jun 19, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/dogfood, @objectstack/spec, @objectstack/verify.

89 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/cloud-artifact-api.mdx (via packages/spec)
  • content/docs/concepts/cluster-semantics.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/implementation-status.mdx (via @objectstack/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/concepts/packages.mdx (via @objectstack/spec)
  • content/docs/concepts/setup-app.mdx (via @objectstack/spec)
  • content/docs/concepts/skills.mdx (via @objectstack/spec)
  • content/docs/concepts/webhook-delivery.mdx (via @objectstack/spec)
  • content/docs/getting-started/architecture.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/spec)
  • content/docs/getting-started/core-concepts.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/guides/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/guides/ai-capabilities.mdx (via @objectstack/spec)
  • content/docs/guides/airtable-dashboard-analysis.mdx (via @objectstack/spec)
  • content/docs/guides/analytics-datasets.mdx (via @objectstack/spec)
  • content/docs/guides/api-reference.mdx (via @objectstack/spec)
  • content/docs/guides/business-logic.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/error-catalog.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-type-gallery.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-validation-rules.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/protocol-diagram.mdx (via packages/spec)
  • content/docs/guides/cheatsheets/query-cheat-sheet.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/quick-reference.mdx (via @objectstack/spec)
  • content/docs/guides/client-sdk.mdx (via @objectstack/spec)
  • content/docs/guides/common-patterns.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/auth-service.mdx (via packages/spec)
  • content/docs/guides/contracts/cache-service.mdx (via packages/spec)
  • content/docs/guides/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/index.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/guides/contracts/storage-service.mdx (via packages/spec)
  • content/docs/guides/data-modeling.mdx (via @objectstack/spec)
  • content/docs/guides/deployment-vercel.mdx (via @objectstack/spec)
  • content/docs/guides/driver-configuration.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/guides/formula.mdx (via @objectstack/spec)
  • content/docs/guides/hook-bodies.mdx (via packages/spec)
  • content/docs/guides/kernel-services.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/dashboard.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/field.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/flow.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/index.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/object.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/validation.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/workflow.mdx (via @objectstack/spec)
  • content/docs/guides/packages.mdx (via @objectstack/spec)
  • content/docs/guides/plugin-development.mdx (via @objectstack/spec)
  • content/docs/guides/plugins.mdx (via @objectstack/spec)
  • content/docs/guides/project-scoping.mdx (via @objectstack/spec)
  • content/docs/guides/public-forms.mdx (via @objectstack/spec)
  • content/docs/guides/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/index.mdx (via packages/spec)
  • content/docs/guides/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/guides/security.mdx (via @objectstack/spec)
  • content/docs/guides/seed-data.mdx (via @objectstack/spec)
  • content/docs/guides/skills.mdx (via @objectstack/spec)
  • content/docs/guides/standards.mdx (via @objectstack/spec)
  • content/docs/guides/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…f (ADR-0054 Phase 2)

Phase 2 extends the prove-it-runs ratchet to the flow-node class.

- verify: bootStack gains an opt-in `automation` flag that registers
  @objectstack/service-automation, so authored flows are pulled from the registry
  and POST /automation/:name/trigger runs their nodes. Without it, flow execution
  was unreachable through the harness (the dispatcher's automation routes resolved
  no service). Mirrors the existing `multiTenant`/`security` opt-ins; default off.
- dogfood: a self-contained flow fixture (one object + one autolaunched flow whose
  update_record node stamps a record) + the flow-node proof. It authors the flow,
  triggers it over HTTP, and asserts both directions — the targeted record is
  stamped (node executed) AND a bystander is untouched (the input variable wired
  into the node filter, not a blanket update). Runs green end-to-end.
- spec: flow-node class is now `bound` in proof-registry.mts; flow.nodes.type
  carries the proof; the liveness gate enforces it. Three classes now bound:
  field types, RLS, flow nodes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label Jun 19, 2026
@os-zhuang os-zhuang changed the title feat(spec): prove-it-runs proof field + ratchet for the liveness gate (ADR-0054 #1) feat(spec,verify): prove-it-runs proof field + ratchet, and the flow-node Phase 2 proof (ADR-0054 #1 + Phase 2) Jun 19, 2026
…0054)

Unlocks the analytics binding that was previously blocked because its authorable
surface wasn't governed.

- Govern the `dataset` metadata type: new liveness/dataset.json classifies all 19
  authorable props with file:line evidence from the analytics service consumer
  audit (26 live, 1 dead — measures.certified has no runtime consumer). `dataset`
  added to GOVERNED in check-liveness.mts.
- Bind the analytics class: dataset.dimensions.dateGranularity carries the
  tz-bucketing proof (#1982/#2018) — the property whose org-timezone day-bucket
  behavior the proof asserts. proof-registry.mts flips analytics to bound.
- Four high-risk classes now CI-enforced: field types, RLS, flow nodes, analytics.
- README governed-types + high-risk tables updated; changeset description updated.

Verified: liveness gate green (dataset 27 classified); 17 registry tests; the
analytics proof runs green; full dogfood suite 59/59.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
@os-zhuang os-zhuang changed the title feat(spec,verify): prove-it-runs proof field + ratchet, and the flow-node Phase 2 proof (ADR-0054 #1 + Phase 2) feat(spec,verify): prove-it-runs proof field + ratchet, binding 4 high-risk classes (ADR-0054 #1 + Phase 2) Jun 19, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review June 19, 2026 11:00
@os-zhuang
os-zhuang merged commit a8e4f3b into main Jun 19, 2026
18 checks passed
@os-zhuang
os-zhuang deleted the claude/lucid-gauss-t7dd3z branch June 19, 2026 11:01

This branch was successfully deployed

1 active deployment
Preview — 556c1256 Deployed Jun 19, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants