Skip to content

docs(deployment): give the "gate" table its fourth column — the runtime publish surface (#7442) - #7458

Merged
os-help merged 1 commit into
mainfrom
claude/issue-7442-gate-table-fourth-column
Aug 10, 2026
Merged

docs(deployment): give the "gate" table its fourth column — the runtime publish surface (#7442)#7458
os-help merged 1 commit into
mainfrom
claude/issue-7442-gate-table-fourth-column

Conversation

@os-help

@os-help os-help commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7442

The "the gate" table in content/docs/deployment/validating-metadata.mdx documented three CLI commands. Since #4463 P1 there is a fourth door — saveMetaItem runs the same AUTHORING_RULES table on a state: 'active' write, and publishMetaItem runs it on the draft→active promotion — and the table said nothing about it. A reader of that table (human or AI) concluded a Studio save passes no gate. That is false, and it is exactly the mental model that leads someone to add a redundant check or to skip a real one.

Docs-only. One file: content/docs/deployment/validating-metadata.mdx.

Every cell measured, not assumed

The column was derived from the code, not from the issue body. Measured live through the real dispatch path (runRuntimeAuthoringRules) with a throwaway probe against the built workspace:

  • runtimeGatedTypes()['flow']. flow is the only metadata type any rule declares at that door. An object, view, page or dashboard write runs zero rules — measured, all three returned rulesRun: [].
  • Six registry rules carry surfaces: ['cli', 'runtime-publish'], all with runtimeTypes: ['flow']: validateStackExpressions, validateEmptyCombinators, validateReferenceIntegrity, validateFlowTriggerReadiness, validateApprovalApprovers, lintFlowPatterns.
  • Refusals observed on crafted flow bodies: expression-invalid, approval-expression-invalid, flow-trigger-unknown-event, flow-runas-unscoped, filter-empty-combinator, flow-node-write-unknown-field.
  • Advisories observed (never block): flow-template-unknown-field, flow-draft-status-ambiguous, approval-expression-no-empty-policy.
  • Falsified along the way: a flow node naming a non-existent object is not caught at that door. validateObjectReferences reads stack.objects / actions / dashboards / apps and never flows, so the "Object & action name references" row is , not .

So the new column is ✓ᶠ (runs, flow writes only) on six rows, a plain on the Zod row (the per-type safeParse runs on every write, before the gate), and everywhere else.

Four rows added, so the column can be honest

Also dropped visibility aliases from the advisory row — visibility-alias-deprecated was retired by #6318 (confirmed in validate-visibility-predicates.ts, authoring-rules.ts and authoring-rule-input-tier.test.ts).

The closing prose

The sentence at the end of the section ("a stack cannot be published through the one command that happens to skip a check") was written before the fourth surface and reads as a guarantee about publishing in general. It is kept — it is still true of the three commands — and followed by what the fourth door does and does not guarantee: authoring-rule-wiring.test.ts fails if a rule runs at the runtime gate but not on os build ("the two publish verbs must not disagree"), so the door narrows types, never verdicts, with #6285 as the one stated exception.

The section also now documents what #7435 (89d7b35a7) landed: advisories ride back on the save response under advisories, which is a channel a Studio / MCP / AI author can actually read, rather than only a deduped console.warn.

Adjacent drift fixed

The AUTHORING_RULES citation said packages/cli/src/lint/authoring-rules.ts. The file is at packages/lint/src/authoring-rules.ts (packages/cli/src/lint/ contains only corpus.ts, metadata-eval.ts, score.ts). Fixed in the same pass, as triage asked.

Deliberately not done

  • The heading is still ## The one gate, three entry points. content/docs/deployment/cli.mdx:458 links #the-one-gate-three-entry-points; renaming it would break that link and cli.mdx is outside this card's file surface. The body reconciles the heading with the fourth column instead.
  • The sample console transcript still reads Running author-time rules (26); the registry now holds 38 entries. Out of this card's scope — reported on the issue.

Gates run locally

check:nul-bytes, check:doc-authoring, check:docs-audit-scope, check:role-word, check:quick-reference-counts, check:adr-anchors, check:adr-links — all green. MDX compiles (fumadocs-mdx). Note: check:doc-formula-expressions (named at dispatch) does not exist at this HEAD; check:doc-authoring is the doc gate that does.

No changeset — docs-only, skip-changeset.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XAdrnFmbvpLodAR88aoagw


Generated by Claude Code

…me publish surface (#7442)

The table documented three CLI commands. Since #4463 P1 there is a fourth door:
`saveMetaItem` runs the same `AUTHORING_RULES` table on a `state: 'active'`
write, and `publishMetaItem` runs it on the draft→active promotion. A reader of
the old table concluded a Studio save passes no gate — false, and exactly the
mental model that leads someone to add a redundant check or skip a real one.

Each cell measured against the code rather than assumed. `runtimeGatedTypes()`
returns `['flow']` and six registry rules declare `surfaces: ['cli',
'runtime-publish']`, so the column is `✓ᶠ` (runs, flow writes only) on those
rows and `—` everywhere else; the Zod row is a plain `✓` because the per-type
`safeParse` runs on every write. Findings measured live through the real
dispatch path: `expression-invalid`, `approval-expression-invalid`,
`flow-trigger-unknown-event`, `flow-runas-unscoped`, `filter-empty-combinator`,
`flow-node-write-unknown-field` refuse; `flow-template-unknown-field`,
`flow-draft-status-ambiguous`, `approval-expression-no-empty-policy` ride back
as advisories. An `object` / `view` / `dashboard` write runs zero rules.

Four rows added so the column can be honest: two runtime-gated rules had no row
at all (empty filter combinators #5330, the flow half of the reference-integrity
suite), flow trigger readiness moved out of the "Advisory:" row it had outgrown
(#5762 promoted it to gating), and the runtime-only platform-schedule
organization refusal (#6285) shows the column is not a pure subset in the other
direction either. Dropped `visibility aliases` from the advisory row —
`visibility-alias-deprecated` was retired by #6318.

Also documents what #7435 landed: advisories reach the author on the save
response, not only a server log. Closing prose now says what the fourth door
does and does not guarantee — the wiring test requires every runtime-publish
rule to run on `os build` too, so the door narrows types, never verdicts.

Adjacent citation drift fixed in the same pass: `AUTHORING_RULES` lives in
`packages/lint/src/authoring-rules.ts`, not `packages/cli/src/lint/`.

Fixes #7442

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

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 10, 2026 1:18pm

Request Review

os-help commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator Author

Check Changeset is red, and neither remedy is mine to apply. Flagging rather than fixing.

The failure is exactly what it says — this PR adds no changeset:

This PR adds no changeset. If it releases nothing […] apply the skip-changeset label; otherwise run pnpm changeset and name the packages.

That leaves two routes, and the dispatch ruling for #7442 closes both to me:

So the fix is one label on this PR: skip-changeset. Every other check is unaffected by it, and the gates this card was dispatched with all pass locally (check:nul-bytes, check:doc-authoring, check:docs-audit-scope, check:role-word, check:quick-reference-counts, plus check:adr-anchors / check:adr-links; fumadocs-mdx compiles the page).

Not pushing anything for this one — a commit cannot clear it, and the label the gate is asking for is the PM's to place.


Generated by Claude Code

@os-help os-help added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/m labels Aug 10, 2026 — with Claude
@os-help
os-help marked this pull request as ready for review August 10, 2026 13:54
@os-help
os-help added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit 45cd354 Aug 10, 2026
27 of 28 checks passed
@os-help
os-help deleted the claude/issue-7442-gate-table-fourth-column branch August 10, 2026 14:20
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 skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: the "the gate" table has no fourth column for the runtime publish surface (#4463 P1 shipped one)

1 participant