Repository navigation
finding: one stack can author two entries under one name in 20+ named collections (objects, pages, flows, permissions, webhooks …), and os validate exits 0; only actions and the functions array (#22902) refuse it #22934
Description
Filing gate ①, class (c) candidate: metadata an author or AI can write twice under one name, accepted at a public door with no finding. reach: os validate --json exits 0 with valid: true and no finding naming the duplicate, measured on 20 keys (below). The downstream loss per key is NOT MEASURED, and that is this card's first work item.
Filed by domain:spec seat 1 (#6017) · os-warren · session session_019G5ZnRrTMiwcHG6iZM19zf, from the census in PR #22931's body (#22902's dev, report 6117331386). Triage's grade of #22902 (6114801402) asked for exactly this: "Siblings that show the same silent loss go to one batch card, filed at claim, ⛔ not one card per key." ⛔ Not a claim.
Reader who acts: triage grades it and names the lane. The refusals would sit in packages/spec/src/stack.zod.ts, beside collectDuplicateActionKeyErrors and PR #22931's collectDuplicateFunctionNameErrors, so it reads as domain:spec unless triage routes it elsewhere.
What is measured (PR #22931's census, at 70c36c1151)
Method: take examples/app-showcase's defineStack output, duplicate one key's first entry, re-run defineStack, and run os validate --json on a fixture that does the same. Keys the examples do not author were measured with hand-written entries through defineStack only.
Accepted by defineStack and by os validate (exit 0, valid: true, no finding naming the duplicate): objects (showcase_account; the only new findings are field-no-consumers on the copy), datasources, pages, dashboards, reports, datasets, flows, jobs, emailTemplates, books, positions, permissions, capabilities, sharingRules, webhooks, hooks, mappings, analyticsCubes, connectors, plugins.
Accepted by defineStack (hand-written entries, os validate not run): picklists, docs, agents, tools, skills, a named views entry; apis sharing a name on different paths (refused only by METHOD + path); apps on a manifest.type: 'module' package (refused only by the single-app count on an app package).
Already refused in one stack: actions (collectDuplicateActionKeyErrors, scope-qualified key) and the functions array (PR #22931, in review).
Not measured, and why it decides the batch
- What each key does with the second entry downstream: last wins, merged, both kept, or refused later at boot. For
functionsthe two paths diverged (the build kept the first underkc_a; a source boot kept the second), which is the defect finding: a stack'sfunctionsarray accepts two entries authoring onename, andobjectstack buildexits 0 shipping the second under a suffixed name (onmain, not callable after load), wherecomposeStacksalready refuses a duplicate function name #22902 fixes. ⚠️ Some keys may merge duplicates by design.composeStacksmergesobjectsby name across stacks (COMPOSE_KEY_DISPOSITIONS, the'objects'disposition), so a same-stack duplicate object may be intended extension semantics, not a loss. A key whose duplicate is merged on purpose leaves the batch, with the reading that shows it.
Direction (not a ruling)
- First, measure each key's downstream behaviour on a source boot and through
objectstack build→loadArtifactBundle, as finding: a stack'sfunctionsarray accepts two entries authoring onename, andobjectstack buildexits 0 shipping the second under a suffixed name (onmain, not callable after load), wherecomposeStacksalready refuses a duplicate function name #22902's dev did forfunctions. - Refuse at the contract only the keys that measurably lose or diverge, one sibling collector (or one shared helper) in the cross-reference aggregate, each finding naming the key, the name and every index, as
collectDuplicateFunctionNameErrorsdoes. - One batch, ⛔ not one card per key. A narrowing, so
Clause-②: no (narrowing)and FROM → TO.
Dedupe
MCP search_issues on this repo, closed included:
duplicate name same stack collection accepted defineStack uniqueness refusal objects pages flows: 28 hits, none on this subject. The nearest are finding: a stack'sfunctionsarray accepts two entries authoring onename, andobjectstack buildexits 0 shipping the second under a suffixed name (onmain, not callable after load), wherecomposeStacksalready refuses a duplicate function name #22902 (thefunctionsmember), composeStacks re-merges bound standalone actions that defineStack already copied into their objects — every bound action appears twice in the composed object's actions #14847 and composeStacks objectConflict: 'merge' — a fixed-shape config object (enable, access, protection, tenancy, lifecycle, userActions, publicSharing, external) the later object declares still replaces the earlier one wholesale (residue of the #14848 collection-only ruling) #16075 (composeStacksmerging), spec(flow): FlowSchema accepts edges whose source/target names no node and repeated (source,target) pairs; the engine then runs the target once per incoming edge #22088 (flow edges).array of named entries no uniqueness check two entries one name stack metadata silently last wins: 3 hits, none on this subject (finding: a stack'sfunctionsarray accepts two entries authoring onename, andobjectstack buildexits 0 shipping the second under a suffixed name (onmain, not callable after load), wherecomposeStacksalready refuses a duplicate function name #22902, metadata-protocol: the twoOS_METADATA_WRITABLEreaders disagree on the legacyOBJECTSTACK_METADATA_WRITABLEspelling, so the listing advertises the hatch for a type the save door then refuses #22411, Semantic-entry id uniqueness in the migration registry is guarded only by the shard FILENAME rule — no runtime assertion would see a duplicate #19732).- CONTROL: both queries return finding: a stack's
functionsarray accepts two entries authoring onename, andobjectstack buildexits 0 shipping the second under a suffixed name (onmain, not callable after load), wherecomposeStacksalready refuses a duplicate function name #22902, the family's own card, so the instrument reaches it.
Dedupe words: duplicate name same stack collection; array of named entries no uniqueness refusal; two objects one name accepted defineStack; same-stack duplicate metadata name siblings.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 12, 2026
Unlocked: #22902 closed (PR #22931 merged as
147a0d1acc). Transitionpm:blocked→pm:queuefor the builddomain:specseat 1 (#6017) ·os-warren· sessionsession_019G5ZnRrTMiwcHG6iZM19zf· 2026-10-12T09:17Z.collectDuplicateFunctionNameErrorsis onmain. The build sheet is stage 0's accepted plan (report6120008386, ACCEPT6120079730): 27 keys, one collector, about +450 lines,Clause-②: no (narrowing), and a contract-tier review before the queue.packages/spec/src/stack.zod.ts. That is ordinary concurrency, and the later lander mergesmain.Blocked-by: #22902line is removed.objectstack-fleet commentedon Oct 12, 2026
Claim: PM loop round 1 (#22934 build: the same-stack duplicate-entry refusal for 27 named collections, built from stage 0's accepted plan, report
6120008386build_planand ACCEPT6120079730) · 2026-10-12T09:52ZSession:
session_019G5ZnRrTMiwcHG6iZM19zfAccount:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-22934-duplicate-entry-batchWorktree:
objectstack-issue-22934Domain:
domain:specSeat:
domain:spec#1(seat post #6017)File surface (at
origin/main8e4a2302aor later; stop on breach and explain in the report):packages/spec/src/stack.zod.ts: one frozen identity table and one collector in the cross-reference aggregate, pushed fromvalidateCrossReferencesbesidecollectDuplicateActionKeyErrorsandcollectDuplicateFunctionNameErrors.deriveViewContainerObjectmoves frompackages/metadata/src/view-container.ts(domain:engine, declared cross-lane in this act) into a spec module, and@objectstack/metadatare-exports it under the same name. One copy, never a second.packages/spec, and the existing pins and fixtures the refusal reaches, found by a consumer-radius grep.check:generatednames, and one.changeset/22934-*.md(Clause-②: no (narrowing); the level followscheck-changeset-no-majorand finding: a stack'sfunctionsarray accepts two entries authoring onename, andobjectstack buildexits 0 shipping the second under a suffixed name (onmain, not callable after load), wherecomposeStacksalready refuses a duplicate function name #22902's precedent).Container & model:
M(about +450 lines over 6 files, stage 0's estimate),mode:subagent,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate";Clause-②suspect onstack.zod.ts). A narrowing owes a review atCONTRACT_REVIEW_TIERbefore the queue, by an isolated at-tier subagent.Clause-②: no (narrowing)
Responsibility:
the cross-reference aggregate in packages/spec/src/stack.zod.ts accepts a second same-identity entry for 27 named collections, and the boot keeps the last, or diverges (datasources, hooks, docs) | none: os validate exits 0; only actions and the functions array are refused | any author or AI writing a stack, measured through os validate and two boot doors in stage 0Thread-read: 6121316349
Serial constraints cleared (all open PRs' file lists read at 2026-10-12T09:51Z):
stack.zod.ts. That is ordinary concurrency, and the later lander mergesmain.packages/metadata/src/view-container.ts. Neither file is aSINGLE_CLAIM_PATHSentry.This act moves the card
pm:queue→pm:dispatchedand assignsos-warren.feat(spec)!: refuse a duplicate identity inside one stack's named col…
feat(spec): key emailTemplates by (name, locale); D3 entry, changeset…
chore(spec): regenerate api-surface for deriveViewContainerObject (#2…
test(cli): build the same-package permission-set twin through strict:…
objectstack-fleet commentedon Oct 12, 2026
os-dev-report
{
"issue": 22934,
"status": "done",
"branch": "claude/issue-22934-duplicate-entry-batch",
"pr": "#23031",
"session": "session_019G5ZnRrTMiwcHG6iZM19zf (mode:subagent, the parent PM session id from claim 6121863164)",
"premise_still_valid": true,
"base": "4e6b2709991e4238a55e159bef7f9c102e2edb3b (origin/main at worktree creation); origin/main 9432bac merged in as 9442d4b (disjoint files: flows / notify-node). PR head 9442d4b.",
"summary": "Built stage 0's accepted plan. packages/spec/src/stack.zod.ts gains one frozen identity table SAME_STACK_ENTRY_IDENTITY (27 keys: identity reader, subject, measured consequence, remedy) and one collector collectDuplicateEntryErrors, pushed from validateCrossReferences before the object-count early return beside the action-key and function-name collectors: one finding per (key, identity) collision naming the key, the identity and every index, envelope StackCrossReferenceError / STACK_CROSS_REFERENCE_INVALID / 422, twins included, skipped under strict:false. deriveViewContainerObject moved into packages/spec/src/ui/view-container-object.ts (exported from the spec root and ./ui) and @objectstack/metadata re-exports that one declaration under the same name at its root and /view-container. Two measured deviations from the plan: emailTemplates is keyed by (name, locale) because an i18n bundle is one name across several locales (the spec's own stack-email-template-locale-floor pins went red under name-only, and the registry's ITEM_KEY_DISCRIMINATORS keys email_template by that pair), so 24 keys, not 25, are keyed by name; and a views entry that is not an aggregated container is keyed by its name, the slot every registrar files it under. One fixture outside the spec needed a change (cli permission-set-name-collisions, built through strict:false). Changeset level minor for spec plus patch for metadata, one D3 semantic entry, Clause-②: no (narrowing). The PR is not Tier H/S governed; it owes the contract-tier review before the queue.",
"assumptions": {
"A1": "HOLDS at 4e6b270: a probe through defineStack from source accepted a same-identity pair for all 27 keys (27/27 ACCEPTED, before any edit). The ablation leg re-shows it through the pin file: with the push line removed, 60 refusal cases go red.",
"A2": "HOLDS for the four examples (configs load through the rebuilt spec at 9442d4b; os validate --json exit 0 on all four and os build exit 0 on crm, showcase, multi-package at e9e921b). Package test fixtures: 1 changed. packages/cli/src/utils/permission-set-name-collisions.test.ts, case 'the SAME package declaring its own set name twice is NOT a collision', authored a byte-identical permission-set twin through strict defineStack on purpose; it now builds that package through { strict: false }, assertion unchanged. Radius = every test file outside the spec calling defineStack( (186 files, 22 packages); 160 ran green against the rebuilt spec dist, 26 cli .e2e.test.ts (nightly tier, in neither PR project) NOT MEASURED. A static AST scan of 8483 tracked .ts files for array literals under the 27 keys repeating a literal identity found 19, none reaching strict defineStack (lintConfig raw inputs, core position rows, a dogfood declaredPositionNames input). A second fixture class the plan did not foresee was caught in the spec suite itself: 4 email-template i18n-bundle pins (deviation 1), fixed in the collector, not in the fixtures.",
"A3": "HOLDS and widens: check:api-surface moved by one export on . and ./ui (regenerated with gen:api-surface), and export-origins/ moved too (regenerated with gen:export-origins; the spec suite's export-origins freshness pins caught it). Neither hand-edited; check:generated exit 0 at 9442d4b."
},
"tests": "All exits captured before any pipe; heavy runs through os-verify-lock. (1) Pin file packages/spec/src/stack-duplicate-entry.test.ts: 138 passed (per key a refusal asserting name, code, status, issue count, header, subjects and every index; per key a twin case; cross-collection 3+2 indices; object-less; map keys spelling one explicit name; named+unnamed container; same-named apps on an app package; joined envelope with action-key and function findings; controls: 27 distinct-identity, 19 map-form, email i18n bundle, cross-scope action pair, plugins/agents/picklistExtensions repeated, 27 strict:false). (2) Ablation of the push line at committed e9e921b via scripts/ablation-replace.mjs, anchor 'errors.push(...collectDuplicateEntryErrors(config));' hit 1 -> 0, blob 6dd315756e28 -> 48864d7b1e4d; RED 60 failed | 78 passed (138); restore: blob == HEAD 6dd315756e28, git diff HEAD empty, anchor back to 1; GREEN 138 passed. Subject imported from source (./stack.zod), no dist leg owed. (3) @objectstack/spec full suite at 9442d4b: 652 files, 19606 passed, 1 todo (VERDICT command-exit 0); pre-merge run at c1c13cb was 6 failed (4 email-template pins, 2 export-origins freshness) - both causes fixed. spec typecheck exit 0, check:generated exit 0 (14 artifacts up to date). (4) @objectstack/metadata full suite 58 files 871 passed; typecheck exit 0. @objectstack/cli typecheck exit 0. (5) Consumer radius against spec dist built at 21d95f9 (cli closure build, 59 tasks, VERDICT command-exit 0): cli unit tier 27 files 369 passed + 1 failed (the fixture above; its file 10/10 after the change), cli integration tier 25 files 190 passed (lock held 17m41s, the wrapper printed a holder-side starvation advisory), qa/dogfood 47 files 347, runtime 11/171, verify 14/135, objectql 4/127, plugin-security 5/103, plugin-webhooks 1/46, lint 3/76, create-objectstack 3/73, plugin-auth 2/37, service-analytics 3/35, service-datasource 2/29, app-todo 2/27, plugin-dev 1/20, metadata-protocol 1/19, cloud-connection 1/17, plugin-email 1/17, metadata 2/16, core 1/12, app-crm 1/7, client 1/2 - all exit 0; app-showcase 2 files first failed to resolve unbuilt @objectstack/connector-slack (environmental), after building it 45 passed. (6) Gates at 9442d4b: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 97; 96 run, every one exit 0 (incl. check:api-surface, check:generated, check:lean-entry-closure 15 packages admitted set held, check:dual-build-cjs-loads 107 entries / 66 packages after building 8 unrelated packages whose missing dist made the first sweep exit 3 PREREQUISITE NOT MET, check:nul-bytes, check:adr-0087-registration --base origin/main, check:changeset-no-major --base origin/main, check:empty-changeset); pnpm check:type-check-debt NOT MEASURED (excluded by the dispatch). Reconciled: dispatch-gates --ran with an exit-annotated record -> '97 derived famil(ies) accounted for - 96 run, 1 NOT-MEASURED', exit 0. (7) Lint, a declared narrowing: pnpm exec eslint --no-inline-config --format json over the 11 changed .ts files at 9442d4b, exit 0, 11 files linted, 0 errors, 0 warnings; population from eslint.config.mjs (files **/.{ts,tsx,mts,cts,js,jsx,mjs,cjs} minus NEVER_LINTED; all 11 inside it); count from the JSON output; invariance: the config never enables type-aware linting (no parserOptions.project, eslint.config.mjs lines 326-328), so the diff cannot move an untouched file's verdict. Full pnpm lint is CI's. (8) Control-byte self-scan of changed files: no match.",
"size": "+846 / -88 = 934 changed lines over 16 files (generated: 4 lines, api-surface/root.json, api-surface/ui.json, export-origins/root.json, export-origins/ui.json). The plan estimated about +450: the pin file is 417 lines (138 cases) and stack.zod.ts +214/-1 (table and docblock). Under the 3000-line human-merge threshold.",
"mcp_calls": "0 - no MCP GitHub tool called",
"api_writes": "2 - both through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): (a) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/23031/assignees [os-warren], run 38241750623, read-back 13911 bytes sent, 13911 stored, identical; (b) this os-dev-report comment -> POST /repos//issues/22934/comments via scripts/pm/post-stamped.mjs. Zero label writes: the dispatch named no label and the PR carries a changeset, so skip-changeset does not apply. Zero PR body edits. git pushes are not REST. REST reads only otherwise (issue 22934 and its comments, pull 23031).",
"deviations": [
"emailTemplates identity is (name, locale), not name: measured by the spec suite's own i18n-bundle pins and declared by ITEM_KEY_DISCRIMINATORS. The ruling's intent holds (a same-locale pair, stage 0's measured case, is refused).",
"views: a non-container entry is keyed by its name (registrar rule), an aggregated container by its derived object as planned.",
"Role file over dispatch: the dispatch allowed up to 2 PR body edits; the role file says the dev writes the PR body once and names any correction for the seat. One correction is owed (next item); no PATCH was sent.",
"PR body correction for the seat to apply (Verification record, Consumer radius bullet): replace '
cliunit tier: 78 files, 369 passed and 1 failed, the fixture below, whose file passes 10 / 10 after the change.' with 'cli: of its 78 files, the 27 in theunittier ran 369 passed and 1 failed, the fixture below, whose file passes 10 / 10 after the change; the 25 in theintegrationtier ran 190 / 190; the 26*.e2e.test.tsfiles are in neither PR tier and are NOT MEASURED here.' and in the same bullet '(186 files, 22 packages) ran against' with '(186 files, 22 packages; 160 of them ran) against'. The body states 78 unit-tier files; the unit project ran 27 of them.","Merged origin/main (9432bac) into the branch before opening the PR (AGENTS.md multi-agent section 10); the spec was rebuilt and its full suite, typecheck and check:generated re-run at the merge, plus the final gate sweep. The consumer radius ran before the merge, against the pre-merge spec dist (the merged commits touch flows / notify-node only).",
"The harness attribution reminder asks for a model-named Co-Authored-By trailer; commits carry the model-free pair AGENTS.md requires (Claude-Session + Co-authored-by: Claude). The merge commit 9442d4b is git's default message with no trailer.",
"Pushed the empty branch before any edit (role rule 1)."
],
"open_questions": [
{
"question": "ADR-0048 section 3.4 leaves an author shipping two page/home in one package to authoring-time hygiene (os lint's naming/namespace-prefix advisory). This PR refuses that same-package case at the contract for 27 collections. Is that a reading of the ADR, or a reversal that needs an amended status line (Prime Directive 13)?",
"options": [
"A: a reading. 3.4's decisions (cross-package coexistence; same-package re-registration on reload) are untouched, and the authoring case it delegates is tightened from a warning to a refusal, as collectDuplicateActionKeyErrors already did for actions. Record it in the contract review; no ADR edit.",
"B: a reversal. Add a one-line amended status to ADR-0048 3.4 (a Tier H governed file, so a separate PR)."
],
"recommendation": "A. Business need: stage 0 measured silent loss on all 27 keys at two boot doors, and the advisory reaches only os lint, not validate, build or serve. Long-term: the contract is the one door every path shares (contract-first), and the actions precedent already stands. AI-proofing: a refusal at load is the stronger structural guard against an AI writing two entries under one name; a lint warning is skimmable. Startup focus: no new surface and no new gate, and a separate governed ADR edit would add a Tier H landing for no change in behaviour. Flagged in the PR's Acceptance notes so the contract reviewer rules on it."
}
],
"out_of_scope_findings": [
"carrier: this PR (stage 0's note, in Acceptance notes) · noted, not filed · composeStacks misattributes a same-stack duplicate object as 'defined in multiple stacks' (STACK_COMPOSE_OBJECT_CONFLICT); the batch removes the authored path to it.",
"carrier: this PR (stage 0's note, in Acceptance notes) · noted, not filed · os build's summary counts duplicates as distinct entries and the registry's overwrite notices print below warn; both disappear once the batch refuses.",
"carrier: none (承接者:无) · noted, not filed · os lint's intra-package duplicate advisory (duplicateNameIssues, packages/cli/src/commands/lint.ts: apps, pages, dashboards, flows, reports, datasets) can no longer fire on a top-level stack that strict defineStack built; reachable only for strict:false stacks and hand-built package bodies. Dead-code observation, in Acceptance notes.",
"carrier: the next edit to that import · noted, not filed · packages/objectql/src/engine.ts imports deriveViewContainerObject 'from the LEAF subpath'; @objectstack/metadata/view-container now loads the spec root (98 modules standalone, CJS) and is no longer a leaf, though the comment's reason (keep the manager and filesystem tier out of the lean entry) still holds and the lean closure is unchanged. Outside this claim's file surface, in Acceptance notes."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 12, 2026
✅ ACCEPT: PR #23031 at
9442d4b7f3(Fixes #22934). Next: the contract-tier review, then the queuedomain:specseat 1 (#6017) ·os-warren· sessionsession_019G5ZnRrTMiwcHG6iZM19zf· 2026-10-12T12:14Z · holder of claim6121863164. Report:6123996316. Thread-read: the report.Read in the diff (merge base
9432bac077, 16 files, +846 / −88, 4 generated lines):packages/spec/src/stack.zod.ts: one frozen table,SAME_STACK_ENTRY_IDENTITY, with 27 rows, and one collector,collectDuplicateEntryErrors. The collector is pushed invalidateCrossReferencesbeside the action-key andfunctionschecks, outside the objects guard. It emits one line per (collection, identity) collision and names every index. That is the stage-0 build sheet as accepted.namefor 24 collections.name@localeforemailTemplates, with an untagged entry counting as the floor tag.extendforobjectExtensions.views: an aggregated container uses the object it binds to; any other entry uses itsname, falling back to the same derivation.plugins,agents,picklistExtensions,actions,functions.deriveViewContainerObjectnow has one declaration,packages/spec/src/ui/view-container-object.ts, with no imports. The body is byte-for-byte the removed one frompackages/metadata/src/view-container.ts. Metadata re-exports it under the same name from its root and its/view-containersubpath. The cost is stated in that header: the subpath now loads the spec root entry, andcheck:lean-entry-closure's admitted set for@objectstack/objectql/coreis unchanged.stack-duplicate-entry.test.ts, covers:permission-set-name-collisions.test.tsmoves tostrict: false. Its comment says why: the door it pins must still not misreport a non-strict or pre-refusal artifact.Checklist:
Fixes #22934, correct for the whole card.Clause-②: no (narrowing), as the build sheet set it.@objectstack/specminor, marked BREAKING under the launch-window convention, with a FROM → TO table.@objectstack/metadatapatch. The ADR-0087 marker names the D3 semantic entrystack-collection-duplicate-entry-refused(protocol 18), which has no D2 conversion.content/docs/releases/, no governed path. The twodomain:enginefiles (packages/metadata/**) are the cross-lane surface declared in the claim.mcp_calls0. Writes: the PR create and the report, both over the relay. No label write: the PR carries a changeset.CI at this read: 32 success, 3 skipped,
mergeable_stateclean, draft.Report items, one line each:
cliunit tier ran 27 of its 78 files, and 160 of the 186 files ran) is applied by this seat in the same act as this comment. Under the role file, the dev writes the body once.emailTemplatesidentity is(name, locale), notname. This is a measured correction of the build sheet: the spec's own i18n-bundle pins andITEM_KEY_DISCRIMINATORSkey by the pair. A same-locale pair, the stage-0 case, is refused. Accepted.views: a non-container entry is keyed by its name, the registrars' rule. Accepted.mainmerge9442d4b7fwas made before the PR opened. The contract review reads this head.page/homein one package "stays covered by" theos lintadvisory. This PR refuses that authored case at the contract. The registry's overwrite on reload is untouched.composeStacksmisattributes a same-stack duplicate object: in Acceptance notes, carrier this card. The batch removes the authored path to it.os build's summary count and the registry's sub-warn overwrite notices: in Acceptance notes, carrier this card. Both disappear once the batch refuses.os lint's intra-package duplicate advisory (duplicateNameIssues) can no longer fire on a strict top-level stack: in Acceptance notes. It stays reachable forstrict: falsestacks and hand-built package bodies, so it is not dead, and nothing is filed.engine.ts's import is now stale; the lean closure is unchanged: in Acceptance notes, carrier the next edit to that import. A comment, so nothing is filed.Then: a contract-tier review on this head, isolated from this seat. On PASS: the pre-queue checks, ready, and the queue. The card stays
pm:dispatchedwith its assignee until MERGED.objectstack-fleet commentedon Oct 12, 2026
Queued: PR #23031 at
9442d4b7f3(Fixes #22934). The contract-tier review PASSeddomain:specseat 1 (#6017) ·os-warren· sessionsession_019G5ZnRrTMiwcHG6iZM19zf· 2026-10-12T13:07Z · holder of claim6121863164.6124849864on the PR, atCONTRACT_REVIEW_TIER, on this head, withLocal-runs: none. VERDICT: PASS.defineStack, and amanifest: 'preserve'artifact keeps each package inpackages[i], which the collector never reads. The action-key andfunctionsrefusals onmainare the precedent. This seat's provisional reading in the ACCEPT stands.Clause-②: no (narrowing)is correct on both its arm and its level. It understates one fact:deriveViewContainerObjectis a new export of@objectstack/spec, the shapeclause2-line.mjsspellsyes (narrowing). Both spellings grade the changeset identically. The correction owed isClause-②: yes (narrowing)on the PR body and the changeset together, at the next head made for any other reason. No head is owed for it alone, and none is being made.lastWinsByNamedocblock says 23 collections, but 21 rows use it. Carrier: the next edit to that table.naming/namespace-prefix, but it isduplicateNameIssues. Carrier: a docs-only ADR touch. Not filed.9442d4b7f3:mergeable_stateclean;check-expected-skips --pr 23031exit 0);check-governed-merges --pr 23031: NOT governed, 934 changed lines.pr_readyandautomerge_enablein one relay run.added_to_merge_queueat 2026-10-12T13:06Z.objectstack-fleet commentedon Oct 12, 2026
Landed: PR #23031 →
1959aacd15(Fixes #22934). The card is closed, andpm:dispatchedcomes off in this actdomain:specseat 1 (#6017) ·os-warren· sessionsession_019G5ZnRrTMiwcHG6iZM19zf· 2026-10-12T13:36Z · holder of claim6121863164.1959aacd15. It has one parent and is an ancestor oforigin/main.9442d4b7f3's diff and the landed commit's diff have the same stable patch-id,8fb0cab10138.6120079730, build claim6121863164, ACCEPT6124068670, contract review6124849864(PASS), queued6124892083.defineStackrefuses two entries of one of 27 named collections under one identity. The refusal is oneSTACK_CROSS_REFERENCE_INVALIDfinding (422) per collision, naming the collection, the identity and every index.deriveViewContainerObjecthas one declaration, in@objectstack/spec, and@objectstack/metadatare-exports it under the same name.Clause-②: yes (narrowing)was the exact spelling, because the PR added one new spec export. There is no later head, so it is recorded here and not re-written.lastWinsByNamedocblock count is 23, but 21 rows use it. Carrier: the next edit to that table.naming/namespace-prefixwhere the advisory isduplicateNameIssues. Carrier: a docs-only ADR touch.Fixes #22934. The only issue closed in the merge window is this card.