Skip to content

docs(adr): ADR-0005 still states the overlay uniqueness key as four parts — since 5677add93f (#22877 stage 1) it carries bundle_member (Tier H, the maintainer's hand) #23006

Description

@objectstack-fleet

Filing gate ①, class (b): an accepted record states the current overlay key, and since 5677add93f that statement is false. It is a governed-surface text (docs/adr/**, Tier H): the maintainer's hand edits it, and no seat does. reach: named producer 5677add93f (#22877 stage 1, PR #22954). Readers: every agent and author who reads ADR-0005 for the overlay's uniqueness key.

Filed by domain:engine seat 2 (#20966) · os-steve · session_01ADzJtzYTLUfgrRZHxkagkX · 2026-10-12T09:30Z, at landing, as the ACCEPT on #22877 (6120204973) recorded. The contract-tier review on PR #22954 named it: "ADR-0005's present-tense amendment still spells the current key as four parts — … an amendment line is Tier H, the maintainer's hand: file it". ⛔ Not a claim. Lane and grade are triage's.

What is false on main (read at 5677add93f)

  • docs/adr/0005-metadata-customization-overlay.md:833: "a plain DatabaseLoader boot already stores CREATE UNIQUE INDEX idx_sys_metadata_overlay_active ON sys_metadata (type, name, organization_id, package_id) — the declared index, with the current key". After 5677add93f the declared index carries a fifth column, bundle_member (packages/metadata-core/src/objects/sys-metadata.object.ts).
  • :865, under "What delivers overlay uniqueness today": "(type, name, organization_id, COALESCE(package_id, '')) WHERE state = 'active'". The runtime key is now (type, name, organization_id, COALESCE(package_id, ''), COALESCE(bundle_member, '')), active and draft (packages/metadata-protocol/src/migrations/overlay-index.ts).
  • Re-check: git show origin/main:docs/adr/0005-metadata-customization-overlay.md | grep -n -E "organization_id, package_id\)|COALESCE\(package_id, ''\)\)" against git show origin/main:packages/metadata-protocol/src/migrations/overlay-index.ts | grep -n bundle_member.

The remedy (the maintainer's)

One dated amendment line in ADR-0005's status header, plus the two sentences restated (or annotated) with the five-part key and its reason:

It can ride with any other ADR edit already owed to the maintainer. ADR-0139's E0 status line is one (#22788).

Dedupe

MCP search_issues, closed included: ADR-0005 overlay index key bundle_member four parts → 0 hits on this subject. #22877 (still open: its stage 2 remains) is the producer, not a duplicate.

Dedupe words: ADR-0005 overlay key; idx_sys_metadata_overlay_active bundle_member; overlay uniqueness five-part key.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, documentation · priority:p3 · domain:skills · area:devpath, into pm:queue. Sequenced after PR #23011, which edits the same ADR

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-12T11:08Z. ⛔ Not a claim, ⛔ not a dispatch.

  2. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (#23006 — ADR-0005's present-tense overlay key gains bundle_member, Tier H) · 2026-10-12T11:35Z
    Session: session_012dGTuJen61ECNHXYXKChoC
    Account: os-justin (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23006-adr-0005-five-part-overlay-key
    Worktree: objectstack-issue-23006
    Domain: domain:skills
    Seat: domain:skills#2
    File surface: docs/adr/0005-metadata-customization-overlay.md (the status header's amendment list, and the present-tense statements of the current key in the "what is true today" block: the card's two lines plus the declared-index line beneath them, which the card does not name); conditionally scripts/adr-anchors/packages__metadata-protocol__src__migrations__overlay-index.ts.json and scripts/adr-anchors/packages__metadata-core__src__objects__sys-metadata.object.ts.json (the key spelling in their invariant text only, under the bounded in-place rule, if the dev measures them stale) (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: opus — the default judgment tier; dispatch-gates --tier --repo objectstack-ai/objectstack on the ADR path at 3071d3e98 printed 「Model tier — no path-derived mandate」 (floor sonnet · default opus · ceiling fable); the seat's call is default, not floor, because a governed record's correctness is judged by reading, not by the gate farm
    Clause-②: no
    Responsibility: n/a — not a defect card (an accepted record's present-tense statement went stale; class (b) of the filing gate)
    Thread-read: 6123056260
    Ruling-ref: none on this card. The content follows #22877 ruling 6116165299 (letter A, maintainer 「同意」; fetched in this act), which put the bundled type's member into the overlay key.
    Resume-from: none
    Serial constraints cleared: PR #23011 (#22340 S3, seat 1) edits ADR-0005's status header, the region this card's amendment line lands in, so this card was held behind it until it read MERGED as e4a770d6b (2026-10-12T11:32Z). In-flight claims naming ADR-0005 across all 18 open pm:dispatched cards: only #22340 (that is the control hit). Open PRs changing ADR-0005 among all 19 open: only PR #23011. #22788 (ADR-0139's status line, pm:blocked, domain:engine) is named on the card as a possible rider. It does not ride: it is another card, in another lane, in another file.
    Delivery shape: Fixes #23006; Tier H, so the PR stays draft until an authorized approval.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23006,
    "status": "done",
    "branch": "claude/issue-23006-adr-0005-five-part-overlay-key",
    "pr": "#23037",
    "session": "session_012dGTuJen61ECNHXYXKChoC (subagent: the PM session id; identity is the branch)",
    "premise_still_valid": true,
    "summary": "ADR-0005 now states the five-part overlay key. The status line gains one dated entry, '· Amended (2026-10-12, #22877 ruling A — …)', naming bundle_member, NULL as the canonical member, and producer 5677add (PR #22954). The #6771 measurement sentence is kept verbatim with a dated '2026-10-12 note' after it. Owner 1 states the runtime key (type, name, organization_id, COALESCE(package_id, ''), COALESCE(bundle_member, '')) with its reason. Owner 2 quotes the tree's declaration: five fields, unique: 'global'. H1 confirmed: the full re-grep found 3 present-tense sites at edecd44 (:835/:867/:878), not the card's 2. H2 confirmed from the tree. H3 confirmed stale: both anchor invariants spelled the four-part key, so each got the bounded in-place one-span fix. H4: the anchor citing ADR-0005:53-64 still points at byte-identical lines (BASE vs HEAD diff exit 0). Draft PR #23037 is open, assignee os-justin, label skip-changeset read back. It stays draft: Tier H, the maintainer's approval lands it. CI: in_progress, not waited on (PM owns convergence). Worktree cleanup (node_modules, then git worktree remove) is the step right after this comment.",
    "tests": "Docs and anchor text only, so no package test or typecheck applies (the diff touches no package). Gates on HEAD a75f9f2: all 27 derived commands exit 0 (list in gates). dispatch-gates --ran: '27 derived famil(ies) accounted for — 27 run, 0 NOT-MEASURED (a DERIVED zero — all 27 recorded an exit code and none of them is 3)'. Measurement behind the ADR wording change (Acceptance notes 2): in-memory SQLite (better-sqlite3 12.11.1) with the declared five-column plain CREATE UNIQUE INDEX. Two identical packaged canonical rows (bundle_member NULL): both INSERTED. Two identical zh-CN rows: the second REFUSED with SQLITE_CONSTRAINT_UNIQUE. No ablation: no gate or code changed.",
    "gates": [
    {
    "cmd": "node scripts/check-adr-links.mjs",
    "exit": 0,
    "verdict": "check-adr-links: 730 relative link destination(s) under docs/adr/ resolve"
    },
    {
    "cmd": "node scripts/check-adr-links.mjs --self-test",
    "exit": 0,
    "verdict": "check-adr-links --self-test: discrimination, census, ADR-0046 pin and baseline staleness all verified"
    },
    {
    "cmd": "node scripts/check-adr-symbol-anchors.mjs",
    "exit": 0,
    "verdict": "check-adr-symbol-anchors: 2319 anchors across 142 records resolve"
    },
    {
    "cmd": "node scripts/check-adr-symbol-anchors.mjs --self-test",
    "exit": 0,
    "verdict": "check-adr-symbol-anchors --self-test: every finding class provoked, healthy anchors silent"
    },
    {
    "cmd": "node scripts/check-ci-filter-parity.mjs",
    "exit": 0,
    "verdict": "OK: all 197 declared cross-package glob(s) (144 unique) are covered by core or crosspkg"
    },
    {
    "cmd": "node scripts/check-closing-keyword-parity.mjs",
    "exit": 0,
    "verdict": "check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators)"
    },
    {
    "cmd": "node scripts/check-closing-keyword-parity.mjs --self-test",
    "exit": 0,
    "verdict": "check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red"
    },
    {
    "cmd": "node scripts/check-comment-mask-corpus.mjs",
    "exit": 0,
    "verdict": "comment-mask corpus sweep: 8857 files, 0 disagree, 0 unparseable"
    },
    {
    "cmd": "node scripts/check-scripts-symbol-anchors.mjs",
    "exit": 0,
    "verdict": "check-scripts-symbol-anchors: 3837 anchors across 285 scripts resolve"
    },
    {
    "cmd": "node scripts/check-scripts-symbol-anchors.mjs --self-test",
    "exit": 0,
    "verdict": "check-scripts-symbol-anchors --self-test: every finding class provoked"
    },
    {
    "cmd": "pnpm --filter @objectstack/lint run check:doc-formula-expressions",
    "exit": 0,
    "verdict": "first run exit 3 (PREREQUISITE NOT MET: @objectstack/formula + @objectstack/lint unbuilt); built under os-verify-lock (turbo run build --concurrency=2 --filter=@objectstack/formula --filter=@objectstack/lint, VERDICT command-exit 0, 4/4 tasks); rerun exit 0: self-test 61 cases passed; 22 record-scoped formula example(s) across 473 files / 1388 TS blocks judged clean"
    },
    {
    "cmd": "pnpm check:adr-anchors",
    "exit": 0,
    "verdict": "check-adr-anchors --self-test: 106 assertions; check-adr-anchors: OK (68 anchored file(s), every governing ADR still referenced; 44138 citation(s) across 5846 file(s) resolve)"
    },
    {
    "cmd": "pnpm check:agent-test-spelling",
    "exit": 0,
    "verdict": "check-agent-test-spelling: 0 violations"
    },
    {
    "cmd": "pnpm check:bash32-floor",
    "exit": 0,
    "verdict": "check-bash32-floor: 30 tracked shell file(s) name no bash 4+ construct"
    },
    {
    "cmd": "pnpm check:cli-command-ids",
    "exit": 0,
    "verdict": "check-cli-command-ids: 814 command-id literal(s) across 253 file(s) all resolve"
    },
    {
    "cmd": "pnpm check:cross-package-test-inputs",
    "exit": 0,
    "verdict": "OK: 30 package(s) read outside themselves, all declared"
    },
    {
    "cmd": "pnpm check:doc-authoring",
    "exit": 0,
    "verdict": "doc authoring guard: 18262 customer-facing string(s) across 1356 spec sources clean"
    },
    {
    "cmd": "pnpm check:driver-memory-census",
    "exit": 0,
    "verdict": "check-driver-memory-census: OK"
    },
    {
    "cmd": "pnpm check:entry-guard",
    "exit": 0,
    "verdict": "check:entry-guard: 285 scripts/ file(s), every entry guard goes through invoked-as.mjs"
    },
    {
    "cmd": "pnpm check:gitlink-declared",
    "exit": 0,
    "verdict": "check-gitlink-declared: OK (11048 index entries, 0 gitlink(s))"
    },
    {
    "cmd": "pnpm check:nul-bytes",
    "exit": 0,
    "verdict": "check-nul-bytes: OK (scanned 11039 text file(s); no raw ASCII control bytes)"
    },
    {
    "cmd": "pnpm check:parse-guard",
    "exit": 0,
    "verdict": "check:parse-guard: 284 scripts/ file(s), every TypeScript parse goes through ts-parse.mjs"
    },
    {
    "cmd": "pnpm check:pm-governed-merges",
    "exit": 0,
    "verdict": "check-governed-merges --self-test: 476 assertions; live: the real generator declared 9 output(s) and certified this tree"
    },
    {
    "cmd": "pnpm check:pm-prior-rulings",
    "exit": 0,
    "verdict": "check-prior-rulings self-test: 155 cases pass"
    },
    {
    "cmd": "pnpm check:pnpm-filter-targets",
    "exit": 0,
    "verdict": "check:pnpm-filter-targets: 160/214 --filter occurrence(s) across 44 file(s) resolve"
    },
    {
    "cmd": "pnpm check:refd-timer-probe",
    "exit": 0,
    "verdict": "check-refd-timer-probe: 8851 source file(s) swept"
    },
    {
    "cmd": "pnpm check:watch-hint-literal",
    "exit": 0,
    "verdict": "check-watch-hint-literal: 73 declaration(s) across 4 rostered name(s)"
    }
    ],
    "extra_gates_outside_derivation": [
    {
    "cmd": "pnpm check:overlay-whitelist-table",
    "exit": 0,
    "verdict": "leg 1 0 divergence(s) over 13 type(s); leg 2 0 divergence(s) over 5 allowEnvironmentOverlay true type(s)"
    },
    {
    "cmd": "node scripts/check-published-list-mirrors.mjs",
    "exit": 0,
    "verdict": "OK: 1 published list mirror(s) match their constants line for line"
    },
    {
    "cmd": "pnpm check:dts-closure",
    "exit": 0,
    "verdict": "check-dts-closure: 4 built package(s) swept, 46/46 declared declaration file(s) present"
    },
    {
    "cmd": "pnpm check:engine-double-contract",
    "exit": 0,
    "verdict": "check-engine-double-contract: OK, 999 pinned, 124 in the DEBT ledger, 3 exempt"
    },
    {
    "cmd": "pnpm check:i18n-stale-fill",
    "exit": 0,
    "verdict": "check-i18n-stale-fill: OK (10 bundle set(s), no new stale fills)"
    },
    {
    "cmd": "pnpm check:published-readme-exports",
    "exit": 3,
    "verdict": "NOT MEASURED, reason: prerequisite, needs a full pnpm build of ~40 packages; this diff touches no package and no README"
    },
    {
    "cmd": "pnpm check:console-injection",
    "exit": 0,
    "verdict": "NOT MEASURED, reason: the gate skipped itself, no console dist at packages/console/dist"
    }
    ],
    "gate_derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) on a75f9f2: 3 paths vs merge base edecd44, 27 commands, the same 27 the dispatch listed. The 8 anchor-path-only families were owed because both anchor files changed, and all were run.",
    "line_budget": {
    "file": "docs/adr/0005-metadata-customization-overlay.md",
    "before": 898,
    "after": 908,
    "insertions": 19,
    "deletions": 9,
    "net": 10,
    "budget": "+10 max: within (at the cap)"
    },
    "files_changed": [
    "docs/adr/0005-metadata-customization-overlay.md",
    "scripts/adr-anchors/packages__metadata-protocol__src__migrations__overlay-index.ts.json",
    "scripts/adr-anchors/packages__metadata-core__src__objects__sys-metadata.object.ts.json"
    ],
    "deviations": [
    "Owner 2 (③): beyond the suggested 'five fields + correct the unique value', the trailing sentence 'it still prevents duplicate active overlays … and it stays NULL-distinct on package_id' is restated as 'NULL-distinct on package_id and on bundle_member — NULL for every canonical member, so it holds no canonical row unique'. Reason: after 5677add the old sentence is false for canonical rows, and the SQLite probe in tests measures this. It is in the claim's file surface (a present-tense statement of the current key's effect). The PR body names it as the one sentence the maintainer should read closely.",
    "Owner 2 (③) also gets a one-line parenthetical: "'global' is protocol 18's spelling of the bare true it retired, ADR-0120 D2" (the producer is ef1fcb2).",
    "Commit trailers: AGENTS.md model-free pair (Claude-Session + Co-authored-by: Claude). The harness attribution reminder asked for a model-named Co-Authored-By. os-dev gives AGENTS.md precedence, so the model-named one was not used.",
    "PR body footer: the AGENTS.md session-URL form ('Generated by Claude Code'), not the harness reminder's two-line block. Read back: the relay stored 10783 bytes, identical to what was sent."
    ],
    "mcp_calls": "0 (no MCP tool used, read or write)",
    "api_writes": "3 relay strokes (each one POST /repos/objectstack-ai/objectstack/dispatches as the session, executed by fleet-write.yml as objectstack-fleet[bot]): (1) pr_create, i.e. POST /repos/objectstack-ai/objectstack/pulls (draft forced) + POST /repos//issues/23037/assignees [os-justin], run 38245730528; (2) label-write labels_add, i.e. POST /repos//issues/23037/labels [skip-changeset], run 38245815359, read back MATCHES; (3) this os-dev-report comment, i.e. POST /repos//issues/23006/comments. Also 2 git pushes (the empty-branch probe, then a75f9f2), which are not REST. The card itself got no write: no assignee, no label.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: b · reach: named producer 5677add (PR #22954), the same reach as this card · family: present-tense four-part overlay key in governed records after bundle_member; fold into ONE family closure card, not single-point cards · evidence: at edecd44, docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md:669 ('the overlay-uniqueness index keys on (type, name, organization_id, COALESCE(package_id, ''))') and docs/adr/0126-packaged-metadata-customization-model.md:313 (same key), vs OVERLAY_INDEX_COLUMNS at packages/metadata-protocol/src/migrations/overlay-index.ts:169 · Seam: spec: none (ADR text) → runtime: packages/metadata-protocol/src/migrations/overlay-index.ts#buildOverlayIndexSql · dedupe words: ADR-0029 overlay key bundle_member; ADR-0126 uniqueness index four parts; overlay key family closure",
    "carrier: 承接者:无 (the family closure card above, if opened, can carry it) · noted, not filed · skills/objectstack-data/rules/indexing.md:165, the published skill's partial-index example, quotes the platform's runtime SQL with the four-part key. Drift in an illustration: authors do not write sys_metadata indexes, so it is not class c.",
    "carrier: 承接者:无 · noted, not filed · docs/qa/platform-checklist/areas/cli.json:1125 recreates 'the declared NULL-distinct form' as a four-column CREATE UNIQUE INDEX. The step still seeds the duplicates it needs (both forms are NULL-distinct), so this is unexercised drift only.",
    "carrier: 承接者:无 · noted, not filed · after 5677add the declared coarse fallback (sys-metadata.object.ts:250-254) holds no canonical row unique: it is NULL-distinct on bundle_member, which is NULL for canonical rows (SQLite probe in tests). Its code comment at sys-metadata.object.ts:244-249 still says 'it still prevents duplicate ACTIVE overlays'. No reach measured: no composition was shown to get only the declared tier, so it is not filed. The ADR text in this PR now states the measured fact.",
    "carrier: 承接者:无 · noted, not filed · read-only observation: both overlay indexes keep organization_id bare and NULL-distinct, and environment rows are written with organization_id NULL (ADR-0131 D6; sys-metadata-repository.ts environment-rows read, organization_id null). So the DB-level key does not constrain environment rows on either tier. The overlay-index.ts module header (:117) already names the bare organization_id part as 'a separate question with its own ADR-0120 D4 ceremony'."
    ]
    }

  4. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #23037 @ a75f9f2258 · seat domain:skills#2 · session_012dGTuJen61ECNHXYXKChoC · 2026-10-12T12:09Z

    Checked against GitHub and origin/main, not the report (os-dev-report 6123800633):

    • Shape: draft, base main, first line Fixes #23006, second line Clause-②: no. No other closing keyword in the body. Assignee os-justin; labels skip-changeset, documentation, size/s. The file list matches the claim's surface: ADR-0005, plus the two conditional anchor JSONs, one span each.
    • Content, read on the tree:
    • Changeset: skip-changeset is right; the diff publishes nothing.
    • CI on this head: all 43 check-runs completed, success or skipped. Lint & Repo Gates, TypeScript Type Check and Governed Surface Queue Guard all succeeded. Check Documentation Links first failed in the lychee binary download before any link was checked; the one re-run on this head succeeded.
    • Contract review: PASS at CONTRACT_REVIEW_TIER on this head, comment 6123969188 on the PR, by an isolated subagent of this seat.
    • Landing: Tier H (check-governed-merges --pr 23037: docs/adr/**, 32 changed lines). The PR stays draft until an authorized APPROVED review; then this seat lands it.
    • Deviations accepted (four, as the review judged): the Owner 2 restatement; the 'global' parenthetical; the model-free trailer pair; the session-URL footer.

    Out-of-scope findings, one line each:


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — PR #23037 MERGED as 38d98d8d8 (merged by os-zhuang through the queue: APPROVED review 5491092315 on a75f9f2258, flipped ready, auto-merge, enqueued) · seat domain:skills#2 · session_012dGTuJen61ECNHXYXKChoC · 2026-10-12T13:11Z


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedocumentationImprovements or additions to documentationdomain:skillspriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions