docs(agents): qualify line 8's DB-column item — control plane vs. the metadata tables - #13431
Merged
Merged
Conversation
… metadata tables
`AGENTS.md:8` presents `environment_id` as one of five flagship surfaces of the
v5.0 `project` -> `environment` rename, closing with "No aliases." Measured on
`origin/main`, that item is under-qualified in BOTH directions, and the two
errors point opposite ways:
* On the METADATA tables the column is retired. `sys_metadata` still declares
it, but only as a deprecated nullable legacy column that no writer writes
and the uniqueness discriminator excludes; `sys_metadata_history` dropped it
from its declaration outright in the ADR-0008 SS0 branch/project-removal
amendment. A reader taking line 8 at face value learns to write
`environment_id` into new metadata rows; the spec's own describe() strings
say new code must use `organization_id` only.
* On the CONTROL PLANE the column is fully live and enforced.
`sys_environment_member` is keyed `(environment_id, user_id)` and the
runtime HTTP dispatcher filters on it for the per-project membership 403
gate. So a flat "since deprecated" qualification -- or dropping the item --
would teach the opposite error.
The edit therefore carries the SCOPE rather than a single verdict, in place and
line-neutral. The v5.0 rename statement is untouched: the rename happened, and
the deprecation sits on a later and different axis (environment -> organization,
not project -> environment).
Line-neutral by construction and measured: AGENTS.md stays at 1162 lines
(ceiling 1162, headroom 0) and the widest table row stays 1081 bytes at L720
(pin 1081, headroom 0) -- line 8 is a blockquote, not a table row, so neither
byte ratchet meters it, and the gate's own `scanLineLengths` reports 0 offenders
with line 8 classified `blockquote`.
This was referenced Aug 30, 2026
os-zhuang
approved these changes
Aug 30, 2026
os-zhuang
marked this pull request as ready for review
August 30, 2026 13:35
os-zhuang
enabled auto-merge
August 30, 2026 13:35
This was referenced Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #13368
Governed surface (
AGENTS.md) — draft, human merge. Never flipped ready, never queued, never auto-merge-armed.What changed — one item inside line 8, line-neutral
AGENTS.md:8lists five flagship surfaces of the v5.0projecttoenvironmentrename and closes with "No aliases." Only the DB-column item moves; the rename statement itself is untouched.Before:
After:
Why that shape, and not either of the two the card offered
The card fenced the work as investigation first, then the smaller of (a) qualify the item or (b) drop it. The persistence-layer census says the item is under-qualified in both directions, and the two errors point opposite ways — so a flat "since deprecated" (a) and a deletion (b) would each teach one of them.
Census — which tables still carry
environment_idorigin/mainsys_environment_member(control plane)(environment_id, user_id); the runtime dispatcher filters on it for the per-project membership 403 gatepackages/runtime/src/http-dispatcher.ts:1145; ADR-0002 line 41sys_package_installation(control plane)sys_metadatapackages/metadata-core/src/objects/sys-metadata.object.ts:138-148, 206sys_metadata_history(organization_id, type, name)only since the ADR-0008 section-0 branch/project-removal amendmentpackages/metadata-core/src/objects/sys-metadata-history.object.ts:17-21sys_activity(plugin-audit)packages/plugins/plugin-audit/src/objects/sys-activity.object.ts:264, 287environment_idcolumns — the environment is implicit in the connectionCensus — is any NEW writer left on the metadata tables?
No. Measured, not recalled:
environment_idontosys_metadata. The only remaining metadata-layer touch is a backwards-compat read mapping,packages/metadata/src/loaders/database-loader.ts:702.DatabaseLoader'senvironmentIdoption is accepted for back-compat and ignored: "writes do not setenvironment_idand filters do not constrain on it" (database-loader.ts:75-85).packages/metadata/src/loaders/database-loader.test.ts:403-425asserts the create call carriesorganization_idand notenvironment_id, and that nofindOnewhere-clause has the property.packages/metadata-protocol/src/protocol.tsandpackages/objectql/src/plugin.tsstill describesaveMetaItem"stamping"environment_id. Those files carry zero non-comment occurrences of the column — the comments describe a writer that no longer exists. Out of scope for this PR; filed separately.Why the rename statement stays
The v5.0
project_idtoenvironment_idrename really happened and its terminal migration is still shipped —packages/metadata/src/migrations/migrate-project-id-to-environment-id.ts, whose table list is derived from the declarations that still carry the target column. The deprecation sits on a later and different axis (environment to organization), which is why the qualification is additive and time-marked ("since deprecated") rather than a rewrite of the rename.Landing constraints — re-derived, not recalled
The dispatch flagged uncertainty about which width gate binds line 8. Re-derived from the gate's own output and its own exported scanners:
09f0689d0AGENTS.md is 1162 lines (ceiling 1162; headroom 0)widest table row is 1081 bytes (pin 1081; headroom 0)blockquote;scanLineLengthsreports 0 offendersSo the edit had to be line-neutral and byte growth inside line 8 is unmetered. Measured:
git diff --numstatis1 1 AGENTS.md; the file stays at 1162 lines; line 8 grew 257 to 365 bytes. No ceiling was raised and no pin was touched.Reverse verification (predicted direction stated before running; both legs restored from
HEADand proven byte-identical —git diff HEADempty andgit hash-objectequal to the HEAD blob8802388ed5bd3fafd363108cb3724dd95a5848ce):AGENTS.md is 1163 lines; the ratchet ceiling is 1162, exit 1. The row pin stayed green.AGENTS.md has 1 line(s) over the 120-byte budget: L8 (369B), exit 1. This proves the gate reads this edited line 8, and that the structural blockquote exemption is what keeps it green — not slack.Post-restore the gate returns exit 0 with both AGENTS.md verdict lines green.
Same-day churn
Based on
c813e7ac7(PR #13403, merged 11:22:59Z), which touched Prime Directive 11 near L232 and section 9 near L394. This diff is line 8 only — disjoint from both. Thecheck:pm-governed-prosepinned region on this file is Prime Directive 14, L274 to L331 — also disjoint, and the gate is green.Gates — the derived family, all green at head
09f0689d0, clean treeDerived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no hand-written path list; the script took the change set from the merge base itself). Its eight families match the dispatch list exactly. Exit codes captured before any pipe.Gate verdict lines, quoted from the gates themselves:
check-skill-line-ratchet: AGENTS.md is 1162 lines (ceiling 1162; headroom 0).check-skill-line-ratchet: AGENTS.md: widest table row is 1081 bytes (pin 1081; headroom 0).check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces (docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md) and claim no others.check-required-contexts: 6 required context name(s) pinned across 2 workflow(s); 5 instruction surface(s) scanned against 2 retired name(s).check-nul-bytes: OK (scanned 7438 text file(s) ... no raw ASCII control bytes).check:required-contextsfirst exited 1 withPREREQUISITE NOT MET — the dependency yaml is not installed. That is the gate declining to run, not a finding. Re-run afterpnpm install: exit 0, quoted above.Changeset
None, deliberately — the diff is
AGENTS.mdonly and publishes nothing from any package. This follows the precedent set by PR #13403 on this exact surface (AGENTS.md+CLAUDE.md, no changeset, labelledskip-changeset). Theskip-changesetlabel is applied to this PR; if the Check Changeset gate disagrees, that verdict wins and a changeset gets added.Out of scope — filed, not fixed here
Two findings surfaced by the census; both are separate defect classes and neither is touched by this diff. They are listed in the report comment on #13368 with their filing state.
Generated by Claude Code
Generated by Claude Code