Skip to content

objectql: refuse a (type, name) held twice inside one namespace for the uncovered bucket 2/3 types (ADR-0150 child N) #31670

Open

Description

@objectstack-fleet

epic:#31527#1 · os-project-manager · session_01FEkQ5mLd7pR2PHjsPwiGkz

Filing gate: ④ coordination node: child N of the epic #31527 (parent and per-layer children), as ADR-0150 (docs/adr/0150-behavioural-metadata-addressed-by-package-objects-keep-the-literal-prefix.md, merged in #31586 at 5d1382a)'s execution plan lists it. Hand-over card: filed undispatched as the epic seat signs off (maintainer 2026-11-08T16:34Z 「专题卡当前任务处理完,合并后就下班」). ⛔ Not a claim.
Ruling-ref: per-type table A (6723462584); epic A 「立专题」 (6723499113); division of labour A 「留核心,其余交车道」 (6723571682); D2 (6724570466); ADR-0150 accepted by merge (#31586, 2026-11-08T21:16Z).
Business reason: inherited from the parent #31527. Behavioural metadata is addressed by (package, name), so two installed packages can each ship an item of the same name and every reader answers the right one, or refuses with the candidates, instead of silently taking the first match.
Reader: the next domain:server seat picks it from the queue (pm-dispatch selection) and accepts its PR against the red lines below.
Dedupe (open AND closed): namespace co-owner unique (4; top hits #31527(open) #25792(closed) #25403(closed), none on point: they are this epic, its parent #30806, or unrelated cards).
class: d · type: Feature
Grade: p1, inherited from the parent (self-graded under 「定级你可以自己决定」).

维护者速读

同一个命名空间里如果有两个软件包,它们的行为元数据(页面、报表、队列等 12 类)不能重名,安装和 os validate 时拒绝。这样以后「命名空间 + 名字」永远只指向一个条目。第一方实测 0 处冲突。

What to build

A (type, name) held twice inside one namespace is refused at install and os validate (D2, ruled 6724570466), on the ADR-0130 D3 object check, for the bucket 2/3 types phase 1 does not cover: sharing rule, queue, assignment rule, hook, job, app, page, dashboard, report, book, cube, tool. The refusal names both holders. Lands before G1 and G2, so a qualified address and a face always name one item.

Surface

  • Expected file surface: objectql registry.ts (installPackage), cli validate.
  • Clause-②: no.
  • Narrowing: yes (measured first-party: 0 of 297 HotCRM keys).

Acceptance — the epic's three red lines (every child shares them)

  • Resolution never loosens. No first-registered fallback, no environment-wide guess for a caller with a package, no silent pick.
  • Ambiguity is reported, never guessed. Every refusal and every migration report names every candidate.
  • Independently releasable (red line 3). The PR proves it with ADR-0150's four readings: (a) the phase-1 one-holder tests stay green; (b) bare-name behaviour (URLs, MCP, SDK) is unchanged for every name with one holder, except this card's declared narrowing; (c) any migration is re-runnable and never guesses; (d) its Clause-②: declaration and, where it changes the protocol, its ADR-0087 migration entry.
  • The epic seat is off duty after hand-over: the accepting lane seat checks these lines itself, and a narrowing beyond the declared one goes to the maintainer before landing.

Parent: #31527.

Activity

  1. added
    enhancementNew feature or request
    priority:p1High: required for production / M2
    pm:queueReady for the PM dispatch loop
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-steve · session_01ADHkmPF1skfu2kx89BEXZi

    Claim: PM loop round 1 · #31670 · 2026-11-08T21:30Z · feature (p1; ADR-0150 child N, hand-over card of epic #31527)
    Session: session_01ADHkmPF1skfu2kx89BEXZi
    Account: os-steve
    Branch: claude/project-thread-mjoky7 (the card thread's harness-pinned branch; platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-31670
    Domain: domain:server
    Seat: domain:server#1
    File surface: packages/objectql/src/registry.ts (installPackage, beside the ADR-0130 D3 object check) and a predicate module in packages/objectql/src/, the os validate path in packages/cli/src/, their tests, a changeset (stop on breach; explain in the report)
    Container & model: L, mode:thread, model: default tier (narrowing: the review of record runs at CONTRACT_REVIEW_TIER), effort: xhigh
    Clause-②: no (narrowing)
    Metadata-protocol: narrowed
    Ruling-ref: 6724570466 (D2); 6723462584 (per-type table A)
    Responsibility: n/a — not a defect card
    Thread-read: none
    Premise: holds (read at 5d1382a5: ADR-0150 is on main via #31586 5d1382a5; no same-namespace (type, name) refusal exists for the 12 bucket 2/3 types)
    Serial constraints cleared: seat 1's own draft PR #31661 (#31414, Tier H, waiting on approval) touches registry.ts comment lines and bare-name-one-holder.ts. Same seat, so the dev leaves those hunks alone and rebases on #31661 if it lands first. No other open PR touches registry.ts. ⛔ No package-scoped resolution (child R, #31575). A narrowing beyond the 12 declared types goes to the maintainer before landing.
    Order: standard order + server-seat1/31670-delta.md (project files).

  3. added
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Nov 8, 2026
  4. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-steve · session_01ADHkmQv69sQL5nfT8xuPWs
    os-dev-report

    {
      "issue": 31670,
      "status": "done",
      "branch": "claude/project-thread-mjoky7",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31717",
      "session": "session_01ADHkmQv69sQL5nfT8xuPWs",
      "premise_still_valid": true,
      "summary": "One predicate (packages/objectql/src/namespace-co-owner-names.ts) decides whether a package declares a sharing rule, queue, assignment rule, hook, job, app, page, dashboard, report, book, analytics cube or tool under a name another package of its namespace already holds. SchemaRegistry.installPackage asks it right after the ADR-0130 D3 object check and throws NamespaceNameConflictError (NAMESPACE_CONFLICT, 422, every holder named); os validate and os build walk the artifact's packages[] in the boot's install order and ask the same predicate, with the same sentence. Shareable namespaces (base/system/sys) and packages without a namespace are not judged; #31661's hunks are untouched and merge cleanly with it.",
      "tests": "New: objectql registry-namespace-co-owner-names.test.ts 56 passed; cli utils/namespace-co-owner-names.test.ts + parity 2 files/63 passed; cli test/validate-namespace-name.test.ts 4 passed (row message asserted equal to the door's thrown message). Suites on 97b94ed7: objectql 573/11672 passed; cli unit 406/5754; metadata-protocol 328 passed 4 skipped/22595 passed 26 skipped; rest 395/7627 passed 332 skipped; runtime 563/9033 passed 19 skipped; phase-1 bare-name files alone 4/154 passed. Ablations: door call removed -> 17/56 red; validate branch inverted -> 1/4 red (validate exits 0); walk inverted -> 14/29 red; each restored, git diff HEAD 0 bytes.",
      "gates": "dispatch-gates --ran on 97b94ed7: 84 derived, 84 run, 0 NOT-MEASURED, 0 UNRUN, all exit 0 (check-plugin-teardown-shape --self-test and check:dual-build-cjs-loads first exit 3 on missing prerequisites, re-run green after fetching the fixture commit / building the five dist-less packages). eslint objectql and cli --no-inline-config exit 0; typecheck objectql, cli exit 0. CI check-runs not yet cited (PR just opened).",
      "dogfood_battery": "97b94ed7 · os-verify-lock: VERDICT command-exit 0 · Test Files 440 passed, 3 skipped (443) · Tests 3652 passed, 41 skipped (3693) · no failure",
      "mcp_calls": "4 — issue_read get, issue_read get_comments x2, pull_request_read get_files x1; no write tools",
      "api_writes": "2 — fleet-write relay pr_create (POST pulls, #31717); this comment via post-stamped.mjs (POST issues/31670/comments)",
      "open_questions": [
        {
          "question": "Cold boot: refuse a deployment whose installed packages of one namespace already share one of these names, or only warn at the cold boot like phase 1?",
          "options": [
            "A refuse at every install, boot included, like the ADR-0130 D3 object check (as built)",
            "B judge only after kernel:bootstrapped seals, warn at cold boot"
          ],
          "recommendation": "A, because D2 is ruled as an install refusal on the D3 check and the measured first-party population that would stop booting is 0"
        },
        {
          "question": "Judge the sys namespace too?",
          "options": [
            "A leave base/system/sys out, matching the namespace gate's exemption (as built)",
            "B judge sys as well"
          ],
          "recommendation": "A in this child; showcase's 22 sys packages hold 0 duplicates, cloud's sys packages are not measured, a later child can widen it"
        },
        {
          "question": "Names: NamespaceNameConflictError, namespace-co-owner-names.ts, NAMESPACE_UNIQUE_TYPES / namespacePackageOf / namespaceNameConflicts / namespaceNameConflictMessage; no new error code",
          "options": [
            "A keep",
            "B rename"
          ],
          "recommendation": "A, seat's call per house conventions"
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [],
      "files_changed": [
        "packages/objectql/src/namespace-co-owner-names.ts (new)",
        "packages/objectql/src/registry.ts",
        "packages/objectql/src/index.ts",
        "packages/objectql/src/registry-namespace-co-owner-names.test.ts (new)",
        "packages/objectql/src/federated-injected-column-readers.test.ts (one ledger row, forced)",
        "packages/cli/src/utils/namespace-co-owner-names.ts (new)",
        "packages/cli/src/utils/namespace-co-owner-names.test.ts (new)",
        "packages/cli/src/commands/validate.ts",
        "packages/cli/src/commands/compile.ts",
        "packages/cli/test/validate-namespace-name.test.ts (new)",
        "packages/cli/test/validate-build-gate-parity.test.ts (one roster row, forced)",
        ".changeset/31670-namespace-co-owner-names.md (new)",
        "scripts/adr-anchors/packages__objectql__src__namespace-co-owner-names.ts.json (new)"
      ],
      "line_budget": "13 files, +1235 / -0 vs main (559 source, 648 tests, 28 changeset and ADR anchor)",
      "deviations": [
        "HotCRM census NOT MEASURED (not in this container); first-party measured 0",
        "Base side of Clause-② measured by ablation of the one added call at each door, not on a base checkout",
        "The spawn test is in the cli integration project; also run locally",
        "os-dev-report posted by the card thread; PR assignee/review request left to the seat (no MCP writes)"
      ]
    }

    Stamped 2026-11-08T23:15Z.

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, iteratedomain:serverDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-setpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions