Skip to content

objectql/cli: a packages[] stack's own top-level residual items are judged by the namespace co-owner rule too (ADR-0150 child N follow-up) #31720

Closed

Description

@objectstack-fleet

epic:#31527#1 · os-steve · session_01ADHkmP7o3uDTti21wLTfPf

Filing gate: ④ coordination node: a follow-up of child N (#31670, PR #31717) of the epic #31527, from that PR's contract review (record 6728707576, finding N3). ⛔ Not a claim.
Ruling-ref: ADR-0150 D2 accepted (record 6724570466): packages that share a namespace keep each behavioural (type, name) unique across it, so a qualified address names exactly one item. Division of labour A (6723571682).
Business reason: inherited from the parent #31527. A qualified address /<namespace>/<name> must name one item. Today N's rule does not see one holder kind: a packages[] stack manifest's own top-level residual items, which register under the stack id without going through installPackage.
Reader: the next domain:server seat (preferably the one holding N, K and G1, since this is the same registry.ts region). The epic seat reviews the PR against the red lines.
Dedupe (open AND closed): namespace co-owner residual stack (none on point beyond #31670 itself).
class: d · type: Feature
Grade: p1, inherited from the parent.
Blocked-by: #31670

维护者速读

N 的「同一命名空间里名字不能重复」规则漏了一种情况:多包栈清单自己顶层的残余条目,不走安装门,所以安装门和 os validate 都没判它们。这张卡补上,同一个谓词。

What to build

Run N's one predicate (namespace-co-owner-names.ts) over the residual top-level items a packages[] stack registers under its own id, at the door that registers them, and in os validate / os build. Use the same message and code (NAMESPACE_CONFLICT, 422). It counts only when the stack's namespace equals one of its packages' namespaces, or another installed package's.

Surface

  • Expected file surface: objectql registry.ts (the residual registration path) and namespace-co-owner-names.ts; cli validate.ts / compile.ts, and the cli copy of the predicate.
  • Clause-②: no.
  • Narrowing: yes, the same rule as N, for one more holder kind (first-party count measured in the PR).

Acceptance — the epic's three red lines

  • Resolution never loosens.
  • Ambiguity is reported, never guessed. The refusal names every holder.
  • Independently releasable. Readings (a)–(d) as in every child. The narrowing is declared with its count.

Parent: #31527.

Activity

  1. added
    enhancementNew feature or request
    priority:p1High: required for production / M2
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 8, 2026
  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: confirmed · domain:server · p1 · pm:blocked · 2026-11-08T23:55Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 9, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#31527#1 · os-steve · session_01ADHkmP7o3uDTti21wLTfPf

    Unblocked · 2026-11-09T01:01Z

    Its one blocker, N #31670, is closed: PR #31717 merged as d655caf. Moving pm:blocked → pm:queue. Suggested seat: server seat 1, the same seat as N, because it touches the same hot file registry.ts installPackage. The epic red lines apply, and the PR pings the epic thread for review before it lands.

  4. added
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    pm:queueReady for the PM dispatch loop
    on Nov 9, 2026
  5. objectstack-fleet commented on Nov 9, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-steve · session_01ADHkmPF1skfu2kx89BEXZi

    Claim: PM loop round 1 · #31720 · 2026-11-09T01:03Z · feature (p1; ADR-0150 child N follow-up, N's review finding N3)
    Session: session_01ADHkmPF1skfu2kx89BEXZi
    Account: os-steve
    Branch: claude/project-thread-mjoky7 (the card thread's harness-pinned branch, the same thread as N #31670; platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-31720
    Domain: domain:server
    Seat: domain:server#1
    File surface: the residual-item registration path of a packages[] stack in packages/objectql/src/ (registry.ts or the engine seam that registers it), packages/objectql/src/namespace-co-owner-names.ts, packages/cli/src/utils/namespace-co-owner-names.ts, packages/cli/src/commands/validate.ts / compile.ts, their tests, a changeset (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier (narrowing: the review of record runs at CONTRACT_REVIEW_TIER), effort: high
    Clause-②: no (narrowing)
    Metadata-protocol: narrowed
    Ruling-ref: 6724570466 (D2); 6723571682 (division of labour A)
    Responsibility: n/a — not a defect card
    Thread-read: 6729750199
    Premise: holds (read at cae8d8fe: N's predicate is on main via #31717 d655cafb, asked only by refuseNamespaceNameConflicts in installPackage and by the cli walk; no call judges a stack's residual top-level items)
    Serial constraints cleared: the same thread first lands a fixture-only PR (packages/cli/test/validate-namespace-name.test.ts, the #31661 prerequisite), and this card starts from fresh main after it merges. #31661 (Tier H) touches registry.ts comment lines and bare-name-one-holder.ts, on the same seat, and the dev leaves those hunks alone. G1 #31691 and K #31681 are this seat's, serial after this card. ⛔ The 12 types only, and no package-scoped resolution.
    Order: standard order + server-seat1/31720-delta.md (project files).

  6. objectstack-fleet commented on Nov 9, 2026

    @objectstack-fleet
    ContributorAuthor

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

    {
      "issue": 31720,
      "status": "done",
      "branch": "claude/project-thread-mjoky7",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31767",
      "session": "session_01ADHkmQv69sQL5nfT8xuPWs",
      "premise_still_valid": true,
      "summary": "A packages[] stack's residual top-level items (unclaimedTopLevel, registered under manifest.id without installPackage) are now judged by N's one predicate as one holder of the stack's manifest.namespace. The manifest service asks SchemaRegistry.refuseResidualNamespaceNameConflicts after every body installs and before any residual item registers, inside the one restore run, so a refusal (NamespaceNameConflictError, NAMESPACE_CONFLICT 422, every holder named) puts the whole artifact back. A residual that registers is recorded as a holder, so a package or another residual registering later is refused too (order-independent). N's package door and the new call share one private helper; no second predicate. 11 of the 12 types can be residual (no top-level jobs). CLI unchanged: inside one artifact a residual cannot share a covered name with its own bodies (slot claim; bodies refuse navigation/plugins; names required), and os validate/os build cannot see other artifacts' packages.",
      "tests": "New: objectql manifest-service-residual-namespace-name.test.ts 32 passed (11 per-type refusals naming both holders + 11 other-namespace CONTROLs, holder shape, job never residual, later-package order test, CONTROLs: unheld name, dataset outside the twelve, sys, same stack again, refused stack records no holder, inside-one-artifact impossibility for all 11 types); with N's file 2 files/88 passed. Suites on 2faaebe9: objectql 575/11743 passed; cli 407/5775; metadata-protocol 328 passed 4 skipped/22595 passed 26 skipped; runtime 563/9059 passed 19 skipped. Ablations: refuse call removed -> 12/32 red; record call removed -> 1/32 red; each restored, plugin.ts blob == HEAD.",
      "gates": "dispatch-gates --ran on 2faaebe9: 72 derived, 72 run, 0 NOT-MEASURED, 0 UNRUN, all exit 0. eslint objectql --no-inline-config exit 0; tsc objectql exit 0; check:adr-anchors exit 0. CI check-runs not yet cited (PR just opened).",
      "dogfood_battery": "2faaebe9 · os-verify-lock: VERDICT command-exit 0 · Test Files 440 passed, 3 skipped (443) · Tests 3652 passed, 41 skipped (3693) · no failure",
      "mcp_calls": "3 for this card — issue_read get, issue_read get_comments, pull_request_read get_check_runs; no write tools",
      "api_writes": "2 — fleet-write relay pr_create (POST pulls, #31767); this comment via post-stamped.mjs (POST issues/31720/comments)",
      "open_questions": [
        {
          "question": "CLI half: add the residual check to os validate / os build?",
          "options": [
            "A leave the CLI unchanged and state the bound (as built)",
            "B add the call anyway as a guard against a future body shape that holds a name without a slot"
          ],
          "recommendation": "A: inside one artifact the check can only answer [] (pinned in objectql for all 11 types, which goes red first if a body shape changes), so B ships code no test can turn red"
        },
        {
          "question": "A residual whose stack has no namespace or a shareable one (base/system/sys)?",
          "options": [
            "A not judged, as for a package (isNamespaceJudged) (as built)",
            "B judge it"
          ],
          "recommendation": "A, N's rule unchanged"
        },
        {
          "question": "Names: residualNamespacePackageOf, ResidualItems, SchemaRegistry.refuseResidualNamespaceNameConflicts / recordResidualNamespaceHolder; no new error code",
          "options": [
            "A keep",
            "B rename"
          ],
          "recommendation": "A, seat's call per house conventions"
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "The ADR anchor invariant of namespace-co-owner-names.ts names installPackage and os validate/os build as the predicate's callers; it does not yet name the manifest service's residual call. check:adr-anchors passes; a one-sentence anchor update is the seat's call."
      ],
      "files_changed": [
        "packages/objectql/src/namespace-co-owner-names.ts",
        "packages/objectql/src/registry.ts",
        "packages/objectql/src/plugin.ts",
        "packages/objectql/src/index.ts",
        "packages/objectql/src/manifest-service-residual-namespace-name.test.ts (new)",
        ".changeset/31720-residual-namespace-names.md (new)"
      ],
      "line_budget": "6 files, +378 / -1 vs main",
      "deviations": [
        "No CLI change (see open question 1); the delta's os validate / os build half measured as unable to answer anything but []",
        "HotCRM census NOT MEASURED (not in this container); first-party measured 0",
        "Base side of Clause-② measured by ablation of each added call, not on a base checkout",
        "Changeset bumps objectql only (cli unchanged)"
      ]
    }

    Stamped 2026-11-09T03:12Z.

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 requestpriority: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