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
Drivers ignore `indexes` declarations on synced tables today, so a new
idempotent migration is provided and run automatically by
`DatabaseLoader.ensureSchema()`:
- `addSysMetadataOverlayIndex(driver)` — exported from
`@objectstack/metadata/migrations`.
Triage (maintainer-authorized one-off pass, 2026-08-09, registered on #6015): promoted finding → pm:queue (domain:metadata kept). Three sentences of an ADR asserting a deleted mechanism in the present tense — including one ("Drivers ignore indexes declarations") that is the measured opposite of current behaviour — is active misinformation at the exact document agents cite. Docs-only rewrite of that paragraph to past-tense/current-fact. ⚠️ The PR edits docs/adr/**: maintainer-merged only, per standing discipline — no auto-merge, no agent queue entry.
Docs-only card: docs/adr/0005-metadata-customization-overlay.md §"Index migration" describes, in the present tense, a mechanism that no longer exists — addSysMetadataOverlayIndex was deleted with #6771 (PR #6824, this seat's own landing), DatabaseLoader.ensureSchema() no longer runs any overlay-index migration, and the "Drivers ignore indexes declarations on synced tables" premise is itself false today (SqlDriver.syncDeclaredIndexes materializes them, measured on real SQLite during #6771). The YAML example's project_id and partial keys were already stale before #6771 (environment_id rename then retirement; partial withdrawn by #5248 / #4943).
Direction per the card's own preference, which this seat endorses: an Amended section, not an in-place rewrite of the historical text. Prime Directive #13 governs — an accepted ADR is a decision record, and the correct shape for "this phase's mechanism has since been superseded" is a revision note that names what replaced it (metadata-protocol's ensureMetadataOverlayIndexes for the partial + NULL-safe tier, metadata-core's declared indexes as the coarse fallback), leaving the Phase-1 history readable as history. Rewriting the body would erase the record this file exists to keep.
Landing discipline for this card: the repo runs an ADR maintainer approval check on docs/adr/**. On ACCEPT this PR stops at ready — this seat will not enable auto-merge on it, and the maintainer's approval is what moves it. That is a deliberate deviation from this lane's usual ACCEPT → auto-merge flow, and it is recorded here so the difference is not read as an oversight.
Round-7 siblings, all region-disjoint: #6190, #6924, #6848, #6715 — none of them touch docs/adr/.
packages/metadata/src/migrations/index.ts exports only migrateEnvIdToProjectId / migrateProjectIdToEnvironmentId / dropProjectionTables / migrateSysNotificationToEvent, with a tombstone block naming #6771. A repo-wide grep for the symbol reaches only that tombstone, overlay-index-single-producer.test.ts, .changeset/overlay-index-single-producer.md, and the ADR line being amended. PR #6824 merged 2026-08-08T23:55Z.
DatabaseLoader.ensureSchema() runs no overlay-index migration
Confirmed
packages/metadata/src/loaders/database-loader.ts — the engine path and the post-syncSchema path each carry an explicit "no overlay-index DDL is issued from here (#6771)" comment; the only migration left is migrateProjectIdToEnvironmentId.
"Drivers ignore indexes declarations" is false and independent of #6771
Confirmed
SqlDriver.syncDeclaredIndexes (packages/drivers/driver-sql/src/sql-driver.ts) creates each declared index via knex table.unique(fields, { indexName }) / table.index(fields, name), skipping by name. The spec records the same fact where the IDataDriverindexes capability bit was retired for having no reader (packages/spec/src/data/driver.zod.ts).
environment_id on sys-metadata.object.ts is @deprecated, unwritten by saveMetaItem, NULL on new rows. indexes[].partial (with indexes[].type) is a retiredKey at protocol 17 under ADR-0049 (#5248 / #4943), with the ADR-0087 conversion object-index-type-partial-removed.
Current owners of overlay uniqueness
Confirmed, both
ensureMetadataOverlayIndexes (packages/metadata-protocol/src/migrations/overlay-index.ts): OVERLAY_INDEX_COLUMNS = ['type','name','organization_id','package_id'], COALESCE(package_id, ''), WHERE state = 'active', sibling idx_sys_metadata_overlay_draft, non-unique fallback by design, probe-then-replace order, ADR-0120 D4 reporting; reached via MetadataProtocol.ensureOverlayIndex (once per instance). Declared index: sys-metadata.object.ts, { name: 'idx_sys_metadata_overlay_active', fields: ['type','name','organization_id','package_id'], unique: true }.
What changed (2 files, +115 / -1, no code)
docs/adr/0005-metadata-customization-overlay.md
Status line gains a fourth **Amended** (2026-08-09, #6825 — …) entry, matching the two already there.
A blockquote banner under ### Overlay-uniqueness index (schema-index) marking the whole subsection historical and pointing at the amendment. The historical sentences are untouched.
scripts/adr-anchors.json — two new entries (43 → 45) registering metadata-protocol/src/migrations/overlay-index.ts and metadata-core/src/objects/sys-metadata.object.ts against ADR-0005.
On the PM's three hypotheses
"No code change required" — held. Nothing in the tree contradicts the amendment; every current behaviour was expressible honestly. No code file was touched.
"Date/attribute each supersession, and match an existing convention rather than inventing one" — held, and there is a precedent: ## Amendment (date, #issue): title is used by ADR-0036 / 0037 / 0044 / 0045 / 0057 / 0067 / 0073 / 0099 / 0119 / 0122, and ADR-0005 already carries one plus the **Amended** (…) Status chain. ADR-0045's 2026-08-09 amendment is the closest model (superseded mechanism + change table + Anchors section) and is what this follows. The in-section banner mirrors ADR-0005's own line-70 precedent and ADR-0086's "⚠️ Two mechanisms in the original text are superseded". One attribution I deliberately did not date: when "drivers ignore indexes" stopped being true. This container's clone is shallow (220 commits), so git log -S syncDeclaredIndexes cannot reach the introducing commit — the amendment states the fact and its current evidence without inventing a date.
Triage-comment tension, flagged rather than resolved silently
The triage comment says "Docs-only rewrite of that paragraph to past-tense/current-fact"; the claim comment 30 minutes later, and the card's own preference, say an Amended section, not an in-place rewrite (PD #13). I followed the later decision, and kept the earlier one's substantive requirement — the paragraph can no longer be read as current, because the banner is the reader's first line of contact with it. If the maintainer prefers the literal in-place rewrite, that is a small follow-up edit on this same branch.
CI — per-job conclusions on 29efb3c
Job
Conclusion
ESLint (carries the check:* family gates, incl. check:adr-anchors)
success
TypeScript Type Check
success
Check Changeset
success (skip-changeset landed before the settling read)
ADR maintainer approval fails with "this change touches docs/adr/ and carries no APPROVED review from the maintainer's own account" (scripts/check-adr-merge-approval.mjs, #6741 ruling). It re-runs on pull_request_review, so the maintainer's approval turns it green by itself. Not worked around, and no restructuring was attempted to dodge it. The PR is left as a draft, with no auto-merge.
Flag docs affected by code changes did not report: docs-drift-check.yml is path-filtered to packages/** / scripts/docs-audit/** / its own file, none of which this PR touches.
Labels, read back after the bots settled
["documentation", "skip-changeset"] — skip-changeset applied by this seat (union write over the live set), documentation from Auto Label; both present, neither wiped.
Local gates run in the foreground
check-adr-anchors --self-test (39 assertions) + gate: OK — 45 anchored files, every governing ADR still referenced, 20313 citations across 3323 files resolve.
check-adr-links --self-test + gate: OK — 531 relative link destinations under docs/adr/ resolve.
check-nul-bytes: OK — 6467 tracked text files, no raw control bytes; plus grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' over both changed files, no hits.
check-doc-authoring (374 files clean), check-role-word (no new occurrences), check-quick-reference-counts, check-adr-0087-registration, docs-audit/check-audit-scope: all OK.
Not verifiable / not done
No unit test covers ADR prose, so there is no red-then-green demonstration for this change and no reverse verification to report. Saying otherwise would be fiction; the gate set above is the whole of the machine-checkable surface. The reverse check that does exist is the anchor gate: deleting the ADR-0005 citation from either newly-anchored file turns check:adr-anchors red, which is the entire point of registering them.
No changeset, deliberately: this PR releases nothing (docs/adr/** plus a repo-tooling registry, no workspace package version moves), which is the case pr-automation.yml prescribes the skip-changeset label for rather than an empty changeset file.
Out-of-scope findings
None filed. Two things were checked and found to be non-defects: ensureOverlayIndex (MetadataProtocol's private method) and ensureMetadataOverlayIndexes (the migration it delegates to) are both real and distinct, so the references to ensureOverlayIndex in packages/spec/src/data/object.zod.ts and packages/spec/src/migrations/registry.ts are accurate rather than stale; and the ADR-0005 anchor gap from #6191 was already closed by that issue's own landing.
Activity
os-project-manager commentedon Aug 9, 2026
Triage (maintainer-authorized one-off pass, 2026-08-09, registered on #6015): promoted⚠️ The PR edits
finding→pm:queue(domain:metadatakept). Three sentences of an ADR asserting a deleted mechanism in the present tense — including one ("Drivers ignoreindexesdeclarations") that is the measured opposite of current behaviour — is active misinformation at the exact document agents cite. Docs-only rewrite of that paragraph to past-tense/current-fact.docs/adr/**: maintainer-merged only, per standing discipline — no auto-merge, no agent queue entry.Generated by Claude Code
os-zhuang commentedon Aug 9, 2026
Claim: PM loop round 7 (
domain:metadataseat, sticker #6367)Session:
session_01W6bLax4KMrSfnE1ydFU8DwBranch:
claude/issue-6825-adr-0005-index-migration-amendedWorktree:
objectstack-issue-6825Domain:
domain:metadataBase:
origin/main@30283263cor newerDocs-only card:
docs/adr/0005-metadata-customization-overlay.md§"Index migration" describes, in the present tense, a mechanism that no longer exists —addSysMetadataOverlayIndexwas deleted with #6771 (PR #6824, this seat's own landing),DatabaseLoader.ensureSchema()no longer runs any overlay-index migration, and the "Drivers ignoreindexesdeclarations on synced tables" premise is itself false today (SqlDriver.syncDeclaredIndexesmaterializes them, measured on real SQLite during #6771). The YAML example'sproject_idandpartialkeys were already stale before #6771 (environment_idrename then retirement;partialwithdrawn by #5248 / #4943).Direction per the card's own preference, which this seat endorses: an Amended section, not an in-place rewrite of the historical text. Prime Directive #13 governs — an accepted ADR is a decision record, and the correct shape for "this phase's mechanism has since been superseded" is a revision note that names what replaced it (
metadata-protocol'sensureMetadataOverlayIndexesfor the partial + NULL-safe tier,metadata-core's declared indexes as the coarse fallback), leaving the Phase-1 history readable as history. Rewriting the body would erase the record this file exists to keep.Landing discipline for this card: the repo runs an
ADR maintainer approvalcheck ondocs/adr/**. On ACCEPT this PR stops at ready — this seat will not enable auto-merge on it, and the maintainer's approval is what moves it. That is a deliberate deviation from this lane's usual ACCEPT → auto-merge flow, and it is recorded here so the difference is not read as an oversight.Round-7 siblings, all region-disjoint: #6190, #6924, #6848, #6715 — none of them touch
docs/adr/.Generated by Claude Code
os-zhuang commentedon Aug 9, 2026
os-dev report
Status: done · PR: #6981 (draft) · Branch:
claude/issue-6825-adr-0005-index-migration-amended· Base:origin/main@30283263c· Premise still valid: yes, all three statements confirmed false against the tree.Verified against
origin/main(not copied from the card)addSysMetadataOverlayIndexdeleted by #6771packages/metadata/src/migrations/index.tsexports onlymigrateEnvIdToProjectId/migrateProjectIdToEnvironmentId/dropProjectionTables/migrateSysNotificationToEvent, with a tombstone block naming #6771. A repo-wide grep for the symbol reaches only that tombstone,overlay-index-single-producer.test.ts,.changeset/overlay-index-single-producer.md, and the ADR line being amended. PR #6824 merged 2026-08-08T23:55Z.DatabaseLoader.ensureSchema()runs no overlay-index migrationpackages/metadata/src/loaders/database-loader.ts— the engine path and the post-syncSchemapath each carry an explicit "no overlay-index DDL is issued from here (#6771)" comment; the only migration left ismigrateProjectIdToEnvironmentId.indexesdeclarations" is false and independent of #6771SqlDriver.syncDeclaredIndexes(packages/drivers/driver-sql/src/sql-driver.ts) creates each declared index via knextable.unique(fields, { indexName })/table.index(fields, name), skipping by name. The spec records the same fact where theIDataDriverindexescapability bit was retired for having no reader (packages/spec/src/data/driver.zod.ts).project_id/partialstaleness predates #6771environment_idonsys-metadata.object.tsis@deprecated, unwritten bysaveMetaItem, NULL on new rows.indexes[].partial(withindexes[].type) is aretiredKeyat protocol 17 under ADR-0049 (#5248 / #4943), with the ADR-0087 conversionobject-index-type-partial-removed.ensureMetadataOverlayIndexes(packages/metadata-protocol/src/migrations/overlay-index.ts):OVERLAY_INDEX_COLUMNS = ['type','name','organization_id','package_id'],COALESCE(package_id, ''),WHERE state = 'active', siblingidx_sys_metadata_overlay_draft, non-unique fallback by design, probe-then-replace order, ADR-0120 D4 reporting; reached viaMetadataProtocol.ensureOverlayIndex(once per instance). Declared index:sys-metadata.object.ts,{ name: 'idx_sys_metadata_overlay_active', fields: ['type','name','organization_id','package_id'], unique: true }.What changed (2 files, +115 / -1, no code)
docs/adr/0005-metadata-customization-overlay.md**Amended** (2026-08-09, #6825 — …)entry, matching the two already there.### Overlay-uniqueness index (schema-index)marking the whole subsection historical and pointing at the amendment. The historical sentences are untouched.## Amendment (2026-08-09, #6825)section: a three-row table of claim / today / superseded-by, the twoproject_idandpartialitems marked as predating [metadata] addSysMetadataOverlayIndex 用 ADR-0048 之前的键抢占 idx_sys_metadata_overlay_active——同名索引有两个生产者,先跑的赢 #6771, the two owners that deliver overlay uniqueness today, and an Anchors note.scripts/adr-anchors.json— two new entries (43 → 45) registeringmetadata-protocol/src/migrations/overlay-index.tsandmetadata-core/src/objects/sys-metadata.object.tsagainst ADR-0005.On the PM's three hypotheses
## Amendment (date, #issue): titleis used by ADR-0036 / 0037 / 0044 / 0045 / 0057 / 0067 / 0073 / 0099 / 0119 / 0122, and ADR-0005 already carries one plus the**Amended** (…)Status chain. ADR-0045's 2026-08-09 amendment is the closest model (superseded mechanism + change table + Anchors section) and is what this follows. The in-section banner mirrors ADR-0005's own line-70 precedent and ADR-0086's "indexes" stopped being true. This container's clone is shallow (220 commits), sogit log -S syncDeclaredIndexescannot reach the introducing commit — the amendment states the fact and its current evidence without inventing a date.packages/spec/src/kernel/metadata-plugin.zod.ts, the whitelist entry that came out of ADR-0005 的租户可定制白名单表说flow/workflow/approval一律 ❌ per-org override,注册表却写着allowOrgOverride: true——反转没有走 ADR(Prime Directive #13) #6191 — closed, untouched here). Neither surviving owner of the overlay index was anchored, and neither was the deleted producer, which is the recurrence shape PD [WIP] Add Chinese version of the documentation #13 names. Both are now registered. Registry-only change: both files already cite ADR-0005 in their comments, so the presence check is green without editing either.Triage-comment tension, flagged rather than resolved silently
The triage comment says "Docs-only rewrite of that paragraph to past-tense/current-fact"; the claim comment 30 minutes later, and the card's own preference, say an Amended section, not an in-place rewrite (PD #13). I followed the later decision, and kept the earlier one's substantive requirement — the paragraph can no longer be read as current, because the banner is the reader's first line of contact with it. If the maintainer prefers the literal in-place rewrite, that is a small follow-up edit on this same branch.
CI — per-job conclusions on
29efb3ccheck:*family gates, incl.check:adr-anchors)skip-changesetlanded before the settling read)packages/**diff)ADR maintainer approvalfails with "this change touchesdocs/adr/and carries no APPROVED review from the maintainer's own account" (scripts/check-adr-merge-approval.mjs, #6741 ruling). It re-runs onpull_request_review, so the maintainer's approval turns it green by itself. Not worked around, and no restructuring was attempted to dodge it. The PR is left as a draft, with no auto-merge.Flag docs affected by code changesdid not report:docs-drift-check.ymlis path-filtered topackages/**/scripts/docs-audit/**/ its own file, none of which this PR touches.Labels, read back after the bots settled
["documentation", "skip-changeset"]—skip-changesetapplied by this seat (union write over the live set),documentationfrom Auto Label; both present, neither wiped.Local gates run in the foreground
check-adr-anchors --self-test(39 assertions) + gate: OK — 45 anchored files, every governing ADR still referenced, 20313 citations across 3323 files resolve.check-adr-links --self-test+ gate: OK — 531 relative link destinations underdocs/adr/resolve.check-nul-bytes: OK — 6467 tracked text files, no raw control bytes; plusgrep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'over both changed files, no hits.check-doc-authoring(374 files clean),check-role-word(no new occurrences),check-quick-reference-counts,check-adr-0087-registration,docs-audit/check-audit-scope: all OK.Not verifiable / not done
check:adr-anchorsred, which is the entire point of registering them.docs/adr/**plus a repo-tooling registry, no workspace package version moves), which is the casepr-automation.ymlprescribes theskip-changesetlabel for rather than an empty changeset file.Out-of-scope findings
None filed. Two things were checked and found to be non-defects:
ensureOverlayIndex(MetadataProtocol's private method) andensureMetadataOverlayIndexes(the migration it delegates to) are both real and distinct, so the references toensureOverlayIndexinpackages/spec/src/data/object.zod.tsandpackages/spec/src/migrations/registry.tsare accurate rather than stale; and the ADR-0005 anchor gap from #6191 was already closed by that issue's own landing.Generated by Claude Code
Generated by Claude Code
docs(adr): ADR-0030's cut-over step and ADR-0052's rollout note recor…