Skip to content

ADR-0048 follow-up: marketplace publish-time namespace registration & exclusivity #1825

Closed

Description

@xuyushun441-sys

Context

ADR-0048 v1 shipped the install-time namespace gate (#1810): SchemaRegistry.installPackage throws NamespaceConflictError when a package's namespace is already owned by a different installed package (shareable base/system/sys exempt; same-package reinstall allowed; OS_METADATA_COLLISION=warn downgrades to a warning).

That protects a single environment at install time. The original ADR discussion also raised a publish-time / marketplace half that was deferred: when a vendor publishes a package to the platform/marketplace, the platform should register and exclusively reserve its namespace globally, so two vendors can't both ship crm and collide on a tenant that installs both.

Why install-time alone isn't enough

  • Install-time only catches a conflict after both packages reach the same env. The marketplace can prevent the conflict before distribution.
  • Local dev can't be policed (no central authority) — that's accepted. The marketplace IS the central authority, so it can enforce.
  • Reverse-domain package ids are globally unique (route/identity key, ADR-0048 option A); namespaces (object table prefixes) are not, and a namespace collision is what actually breaks the DB/table layer.

Scope (open-source vs enterprise)

This is enterprise/marketplace surface. The open-source repo keeps the install-time gate + federation hooks; the registration/exclusivity service likely lives in the private marketplace backend. Define the contract here, implement enforcement in the enterprise tier.

Proposed direction (needs ADR-0048 addendum)

  • Publish API: on publish, reserve (namespace → owning package id / vendor) in a platform registry; reject a publish whose namespace is owned by a different vendor.
  • Rename / transfer flow: deferred in the original ADR ("暂不考虑"); revisit whether a vendor can rename a namespace or transfer ownership.
  • Install-time cross-check: optionally consult the platform registry at install so a sideloaded package whose namespace is reserved by another vendor is flagged.
  • Tenant override / alias: per the ADR, namespace may carry a per-tenant friendly alias distinct from the global reservation — confirm how that interacts with exclusivity.

Open questions

  • Granularity of reservation: namespace only, or (namespace, version-range)?
  • What about shareable namespaces (base/system/sys) and platform-owned ones?
  • Grandfathering already-published packages with colliding namespaces.

Acceptance

  • Publishing two different vendors' packages that claim the same namespace is rejected at publish time with a clear error.
  • Documented contract so the open-source install-time gate and the enterprise publish-time gate compose without drift.

Related: ADR-0048, #1810 (install-time gate).

Activity

  1. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    Contributor

    分诊:转决策箱 needs-user-decision,预挂 domain:engine-core。

    分类理由:本单是 ADR-0048 的 publish-time / marketplace 半边 —— 需要 ADR addendum、保留粒度 / 共享命名空间 / 存量灰度(grandfathering)三个 open questions 均属产品契约拍板,且明示为 enterprise/marketplace 面(合约在本仓定义、执行在企业侧落地),不是可直接派发的具体缺陷。按 step 0 分类规则入维护者决策箱;深度三轴分析待实际取卡时再写。

    过时前提检查(origin/main @ b4cdc58):install-time 门禁(#1810)仍是唯一执行点 —— NamespaceConflictError 在 packages/objectql/src/registry.ts:671,带 pin 测试(registry-namespace-install-gate.test.ts);publish-time 注册/独占面自 2026-06-13 立单以来无任何落地。查重:三仓 open issue/PR 搜 ADR-0048 / marketplace namespace,无影子单(cloud#474 是 capability model,不同面)。前提未过时,决策仍待做。

    预挂域说明:开源侧触点是 SchemaRegistry(install-time cross-check 选项)→ domain:engine-core;若维护者裁决后合约面落 docs/ADR 或拆出 cloud 侧执行单,届时按 contract-first 拆分重挂。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. claude commented on Aug 6, 2026

    @claude
    Contributor

    处置(2026-08-06):改标 pm:on-hold(维护者裁:三方 publisher 发布远期/未定)。

    理由:撞名风险仅在三方发布开放后成立;评审管线虽已上线,但 namespace 独占检查在开放前落地即可,现在做属无拉动的能力扩张。

    重启条件(硬,作为开放的验收标准):三方 publisher 开放前必须完成 namespace→publisher 唯一性检查——按最小版 A 执行:评审管线加唯一性检查(现只查 manifest_id 保留前缀,不查 namespace)+ ADR-0048 addendum 记三个默认(纯 namespace 粒度、共享名单沿用 install 闸的 base/system/sys、存量先到先得 grandfather);rename/transfer 继续 deferred。量级(届时)S-M。

    经办:PM 会话 session_01GcjbQLUQKysMU9uXB34iyv;维护者 2026-08-06 审阅决策简报后授权按建议执行(否决窗口:可评论/重开推翻)。


    Generated by Claude Code

  3. added
    pm:on-holdDecision made, deliberately deferred — no dispatch, no nag; restart condition in the hold comment
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 6, 2026
  4. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    Contributor

    【裁决落地】维护者 2026-08-06 批复全舰队决策箱评估报告(批复「同意」),本单裁定:

    准——立 ADR-0048 addendum,定 publish-time / marketplace 全局命名空间独占注册契约。起步口径:保留粒度从纯 namespace 起步(不含 version-range,复杂度不前置);共享命名空间(base/system/sys)白名单、存量 grandfathering、install-time 反查平台注册表三个 open question 在 ADR 内逐条定。

    流转:摘 needs-user-decision → pm:queue,归 engine-core 车道(ADR 起草单);enterprise 面实现随 ADR 结论另行拆单。

    评估与落地会话:session_01N3uGFF8teXbpgtbEJ1aYXu


    Generated by Claude Code

  5. added
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:on-holdDecision made, deliberately deferred — no dispatch, no nag; restart condition in the hold comment
    on Aug 6, 2026
  6. self-assigned this
    on Aug 8, 2026
  7. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    Contributor

    Claim: PM loop round 1 extension 2 (engine-core seat #6019; maintainer raised concurrency to 5+ with cloud cards)
    Session: session_01MwoubC3jL271FYt9rGXwxb
    Branch: claude/issue-1825-adr0048-addendum-namespace-exclusivity
    Worktree: cloud session's own clone (mode:cloud)
    Domain: domain:engine-core
    File surface: docs/adr/0048-*.md (addendum section; prior text kept verbatim per PD #13 if superseded) — ADR text only, NO code. The enterprise-side implementation is split later per the ruling ("enterprise 面实现随 ADR 结论另行拆单").
    Operative ruling note: the thread carries both an 08:28 on-hold disposition and the 10:42 fleet-approved verdict (准 — draft the addendum now); the later verdict matches the card's current machine state (pm:queue) and is the one being executed. Drafting the contract now + implementing before third-party publishing opens satisfies the on-hold comment's hard restart condition rather than contradicting it.
    Serial constraints cleared: no in-flight card touches docs/adr/0048-*; flagship's ADR touch is 0058.
    Container judgment: design card ⇒ mode:cloud (subagent slots full; maintainer directive).


    Generated by Claude Code

  8. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    Contributor

    os-dev final report (#1825)

    Drafted the ADR-0048 addendum defining the publish-time / marketplace global namespace exclusivity contract. ADR text only — no code, no gate changes, no spec changes, per the ruling. Draft PR: #6671.

    Premise re-verified against main @ f123670: the install-time gate (NamespaceConflictError in packages/objectql/src/registry.ts, pinned by registry-namespace-install-gate.test.ts) is still the only enforcement point, and the publish-time surface has zero landing — PackageSchema in packages/spec/src/cloud/package.zod.ts has no namespace field at all, CreatePackageRequestSchema does not accept one, and packages/cli/src/commands/package/publish.ts transmits manifest_id only. The namespace never leaves the artifact. Premise holds.

    Prime Directive #13: nothing in §§1–6 was reversed, so nothing needed marking SUPERSEDED. The addendum is additive to §3.2 and says so explicitly at its head; the install gate's semantics and §3.5's deferral are untouched.

    {
      "issue": 1825,
      "premise_still_valid": true,
      "status": "complete",
      "branch": "claude/issue-1825-adr0048-addendum-namespace-exclusivity",
      "pr": 6671,
      "pr_state": "draft",
      "commits": ["d722c64"],
      "files_changed": ["docs/adr/0048-cross-package-metadata-collision.md"],
      "loc": "+338 / -1",
      "changeset": "none — docs-only; PM to apply `skip-changeset` at acceptance",
      "deliverable": "ADR text only, per the ruling; enterprise-side implementation to be split into separate cards",
      "premise_evidence": [
        "packages/objectql/src/registry.ts — installPackage() namespace gate + NamespaceConflictError + isShareableNamespace() (RESERVED_NAMESPACES {base,system} plus sys); still the only enforcement point",
        "packages/objectql/src/registry-namespace-install-gate.test.ts — gate still pinned",
        "packages/spec/src/cloud/package.zod.ts — PackageSchema carries manifestId/ownerOrgId/visibility/publisher and NO namespace field; CreatePackageRequestSchema does not accept one",
        "packages/cli/src/commands/package/publish.ts — publish flow derives and transmits manifest_id only",
        "packages/spec/src/contracts/package-service.ts — namespaceConflicts/conflicts surfaced on the service contract (install-time only)"
      ],
      "addendum_contents": {
        "status": "Proposed — additive to ADR-0048 §3.2, supersedes no existing text",
        "A.0": "measured current state (install-time only; publish-time surface absent)",
        "A.1": "decisions D1–D6",
        "A.2": "minimal version A — the publish check stated as an algorithm",
        "A.3": "open/commercial boundary",
        "A.4": "explicit non-goals",
        "A.5": "hard activation precondition",
        "A.6": "phasing A1–A4",
        "A.7": "consequences"
      },
      "open_questions": [
        {
          "id": "D1",
          "question": "Reservation granularity — pure namespace, or (namespace, version-range)?",
          "settled_as": "Pure namespace. The reservation record is keyed on the bare namespace string; holder is the publisher org, with the first-claiming manifest_id recorded.",
          "rationale": "Real need: what breaks is a physical table name, and a table name has no version axis — two versions of one vendor's package never collide, two vendors' packages collide at every version pair. Long-term soundness: a range key would let A own crm@1.x and B own crm@2.x while the per-installation, version-blind install gate still collides on them — granting ownership the enforcement layer cannot honour is worse than no key; granularity can only be widened later, so narrow is the reversible direction. AI-safety: one key, one owner, one answer to 'who owns crm?'; a range-keyed registry has an interval-overlap predicate at its heart, and makes 'is this namespace free?' a function of the version being published.",
          "deviation_from_default": false
        },
        {
          "id": "D2",
          "question": "Is the reservation held by the package or by the publisher? (not in the original three, but forced by D1's record shape)",
          "settled_as": "By the publisher org. A publish is rejected only when the namespace is reserved by a DIFFERENT publisher; same-publisher reuse is allowed and records an additional manifest_id under the existing reservation, with a warning.",
          "rationale": "Splits conflicts by whether anyone can resolve them. Cross-vendor is unresolvable by any party and hard-fails — that is what the registry exists for. Same-vendor (com.acme.crm2 succeeding a retired com.acme.crm on namespace crm) is entirely within one party's control, and blocking it would strand a vendor's own namespace behind their own deprecated package with no transfer flow to escape through (transfer is deferred). The install gate still refuses to co-install the pair, which is correct for a successor pair. This is the one place the publish gate is deliberately looser than the install gate; flagged as such in §A.7 so it does not read as accidental drift.",
          "deviation_from_default": false,
          "needs_signoff": true
        },
        {
          "id": "D3",
          "question": "Shared namespaces (base/system/sys) and platform-owned ones — how do they interact with exclusivity?",
          "settled_as": "Whitelist = exactly RESERVED_NAMESPACES ∪ {sys}, read from the same constant the install gate uses. TWO rules: (1) never reserved, never conflict — mirroring isShareableNamespace(); (2) restricted by publisher tier — only publisher: 'objectstack' may publish a package whose namespace is in the whitelist; anyone else is rejected.",
          "rationale": "Real need: the platform genuinely ships many packages under sys (registerNamespace is intentionally many-to-one), so an exclusivity check over them would reject the platform's own composition. Long-term soundness: deriving the set from the same constant is what makes the two gates unable to drift — the issue's 'compose without drift' acceptance criterion, met by construction rather than convention. AI-safety: rule (2) is the non-obvious half — exemption from exclusivity must not read as open season, or the whitelist becomes the cheapest route for a third party to ship objects shadowing platform tables (manifest.zod.ts already declares these platform-reserved and sys_-prefixed object names platform-owned). An agent picking 'system' as a neutral-sounding namespace is refused with a tier reason instead of silently acquiring shadowing rights.",
          "deviation_from_default": false
        },
        {
          "id": "D4",
          "question": "Grandfathering already-published packages with colliding namespaces.",
          "settled_as": "First-come, frozen, shrink-only. Back-fill at switch-on: the publisher of the earliest published version carrying a namespace wins the reservation (ties break on sys_package.created_at, then manifest_id lexicographically — deterministic and re-runnable). Every other publisher already shipping it gets a grandfathered claim permitting new versions of packages that ALREADY EXISTED under that namespace and nothing else — in particular not a new package. The grandfathered set is closed at switch-on and can only shrink.",
          "rationale": "Real need: retroactively invalidating a published package breaks tenants who already installed it; this addendum must not create an outage to close a future hole. Long-term soundness: first-come is the only rule needing no adjudicator, and a shrink-only exception list is the repo's standard ratchet shape — an exception that cannot grow eventually costs nothing. AI-safety: every alternative rule requires judgement ('who deserves crm?'), and a judgement call inside a gate is one an agent will make wrongly and confidently. Noted in the ADR: a grandfathered pair stays un-co-installable — that is the pre-existing state preserved, not a regression — and because third-party publishing is not open, the set is expected to be empty or near-empty at switch-on; a non-trivial back-fill is evidence the switch-on was late.",
          "deviation_from_default": false
        },
        {
          "id": "D5",
          "question": "Whether/how install-time cross-checks the platform registry.",
          "settled_as": "Contract defined, implementation deferred, and it is ADVISORY and FAIL-OPEN, never authoritative. PackageService gains an OPTIONAL namespace-registry lookup port; on mismatch the install surface shows a warning and a trust signal and installs anyway; on lookup failure, timeout, or no platform connection it fails open silently.",
          "rationale": "Real need: the only scenario covered is a sideloaded artifact squatting a marketplace name — a trust problem, not a data-integrity one. Long-term soundness: (a) ADR-0048 §4's 'local development is unaffected until install' is load-bearing and a hard remote check would repeal it; (b) the invariant that matters — no two installed packages in this installation share a namespace — is already fully decided by the in-process Phase 1 gate with no network, so the registry adds provenance, not correctness, and a trust signal that can hard-fail an install turns a marketplace outage into a total install outage across every tenant; (c) advisory can be promoted to blocking later behind a host policy, whereas blocking cannot be relaxed once tenants depend on it. AI-safety: 'advisory, fail-open' is stated as the contract precisely so an implementer cannot read the deferred card as licence to add a network dependency to the install path.",
          "deviation_from_default": false
        },
        {
          "id": "D6",
          "question": "How does the per-tenant friendly alias (§3.6) interact with global exclusivity? (raised in the issue body)",
          "settled_as": "They do not interact. The alias derives from the INSTALLED namespace, whose per-tenant uniqueness comes from the local install gate, not the global reservation; the global registry is never consulted to resolve a route; a tenant cannot alias a namespace it has not installed, and a global reservation confers no alias anywhere.",
          "rationale": "One is a publish-time authority record, the other a tenant-local presentation convenience over the canonical package-id route. The non-interaction is the design, and is stated explicitly because the issue asked.",
          "deviation_from_default": false
        }
      ],
      "activation_precondition": {
        "statement": "The namespace→publisher uniqueness check MUST land before third-party publishing opens — an acceptance criterion for opening it, not a follow-up.",
        "source": "「三方 publisher 开放前必须完成 namespace→publisher 唯一性检查」 (2026-08-06 disposition, quoted verbatim in §A.5)",
        "why_ordering_is_load_bearing": "Every package published before the check exists becomes, by D4, a grandfathered entry the registry can never revoke — so each day the gate is late permanently enlarges a set that is otherwise shrink-only. While publishing is first-party only that set is bounded by our own discipline; the moment it is open it is bounded by nothing. Building it earlier buys nothing (no third-party publishers, no cross-vendor collision), which is exactly why the card sat on hold."
      },
      "commercial_boundary": {
        "precedent": "cloud ADR-0016 iron rule 强制免费、治理收费, as this repo applies it in ADR-0105 D12 (code vs. ACTIVATION, not code vs. code)",
        "open_free": [
          "manifest.namespace and its validation; the namespace field on the publish payload schemas",
          "the install-time gate, NamespaceConflictError, isShareableNamespace(), the shareable-namespace constant, OS_METADATA_COLLISION=warn — all unchanged",
          "the advisory lookup PORT and its fail-open semantics (D5), the error codes, and this contract"
        ],
        "enterprise_paid": [
          "the reservation registry itself — storage, the publish-time gate, ownership records",
          "the D4 back-fill and grandfathered ledger",
          "dispute handling and any future transfer administration"
        ],
        "why_the_iron_rule_holds": "The free half is the half that keeps an installation CORRECT — any deployment, any tier, offline or air-gapped, is fully protected from a namespace collision corrupting its schema, because the local gate refuses the install. The paid half prevents a collision from being discovered LATE and provides an operated global authority to adjudicate names, which is precisely what 治理收费 designates. A deployment without it is never unsafe, only less informed."
      },
      "non_goals": [
        "version-range reservation granularity — actively rejected as a starting position, not deferred pending design",
        "namespace rename / ownership transfer — remains DEFERRED per 「暂不考虑」 and the 2026-08-06 disposition; a reservation is created and released, never moved between publishers (D2's publisher-scoped key is what keeps the absence of a transfer flow from stranding a vendor's own name)",
        "namespace rename-on-install — unchanged non-goal, ADR-0048 §3.5",
        "squatting policy and dispute adjudication — operational marketplace policy, not a protocol decision",
        "any change to install-gate semantics, its shareable set, its same-package-reload exemption, or the OS_METADATA_COLLISION=warn downgrade",
        "enforcement outside the marketplace — local dev, private registries and sideloading are not policed and are not intended to be"
      ],
      "follow_up_cards_implied": [
        "Phase A1 (open, this repo): carry `namespace` on PackageSchema / CreatePackageRequestSchema and have `objectstack package publish` read it off the artifact manifest — prerequisite for everything else; without it the enterprise gate has nothing to check",
        "Phase A2 (enterprise): the publish-time gate (§A.2 algorithm) + reservation store — THIS is the item bound by the activation precondition",
        "Phase A3 (enterprise): the D4 grandfathering back-fill, run once at switch-on, emitting the closed grandfathered set as a reviewable artifact",
        "Phase A4 (deferred): D5's advisory install-time cross-check — explicitly NOT a precondition for A2",
        "ADR-0112 ledger registration of the proposed rejection codes (NAMESPACE_ALREADY_RESERVED / NAMESPACE_RESERVED_PLATFORM) — lands with the implementation, not with this ADR"
      ],
      "gates_run": {
        "source": "enumerated one by one from .github/workflows/lint.yml",
        "all_green": true,
        "eslint_job": ["lint", "check:slot-lookup", "check:query-options-erasure", "check:verify-stand-in", "check:nul-bytes", "check:doc-authoring", "check:docs-audit-scope", "check:role-word", "check:quick-reference-counts", "check:adr-anchors", "check:org-identifier", "check:authz-resolver", "check:service-providers", "check:route-envelope", "check:error-code-casing", "check:wildcard-fallthrough", "check:meta-type-normalized", "check:init-service-contract", "check:durability-log-level", "check:startup-registry-verdict", "check:objectui-changeset", "check:release-notes", "check:release-body", "check:node-version", "check:workflow-status-functions", "check:shard-attestation", "check:published-files", "check:engine-double-contract", "check:resume-authority-declared", "check:merge-driver", "check:spec-parsed-alias"],
        "other_jobs": ["check:i18n", "check:i18n-coverage", "check:skill-frame-sync", "check:skill-compatibility"],
        "notes": [
          "check:adr-anchors green including the ADR-number-uniqueness half — the addendum lives inside the existing 0048 record and claims no new number",
          "check:i18n and check:i18n-coverage initially reported PREREQUISITE NOT MET / COULD NOT MEASURE (they run the built CLI and lint the example configs); after a workspace build both are green — check:i18n OK (9 packages in sync), check:i18n-coverage OK (12 configs, 660 baselined, none new)",
          "the TypeScript type-check job is unaffected — zero .ts/.json files changed"
        ]
      },
      "risks_and_caveats": [
        "D2 (publisher-scoped rather than package-scoped reservation) is the one intentional asymmetry between the publish gate and the install gate. It is the LOOSE direction and only within a single publisher, but it is a judgement call beyond the four fixed defaults and is the item most worth an explicit maintainer nod.",
        "D3's rule (2) — restricting whitelist publishes to the first-party tier — extends the ruling's 'whitelist aligned with the install gate' rather than merely mirroring it. The alignment on WHICH namespaces is exact; the tier restriction is an addition, justified in §A.1 D3 because bare mirroring would make the whitelist an open shadowing route once third-party publishing opens.",
        "§A.2 notes that `namespace` must travel with the publish payload — a real open-side schema change on PackageSchema / CreatePackageRequestSchema. It is scoped OUT of this PR (ADR text only) and recorded as Phase A1, but it means the enterprise card has a hard dependency on an open-repo card landing first.",
        "The marketplace review pipeline's current 'manifest_id reserved prefix' check is enterprise-side and could not be read from this repo; it is described in §A.0 as stated on the issue thread, attributed as enterprise-side, and is not relied on by any decision here."
      ],
      "conduct": {
        "worktree": "/home/user/objectstack-1825 (dedicated worktree per Prime Directive #11; primary checkout detached first)",
        "stash_used": false,
        "assignees_touched": false,
        "releases_dir_touched": false,
        "code_or_spec_touched": false
      }
    }

    Generated by Claude Code

  9. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    and removed
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Aug 8, 2026
  10. removed their assignment
    on Aug 8, 2026
  11. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    Contributor

    PM review passed — handing to the maintainer as decision material (engine-core seat #6019). Label flipped to needs-user-decision: the dev deliverable (ADR-0048 addendum, PR #6671, Proposed, additive to §3.2, nothing superseded) is complete and verified — one file, no code, premise re-measured (publish-time surface still has zero landing; PackageSchema carries no namespace field at all), docs gates green, skip-changeset applied. All four fixed positions from your 2026-08-06 disposition are honored (bare-namespace granularity; whitelist = the install gate's base/system/sys; first-come frozen shrink-only grandfathering; rename/transfer stays deferred), and the hard activation precondition is recorded verbatim in §A.5.

    Two items the dev flagged for your explicit nod (both argued in §A.1, neither contradicts the disposition): D2 — the reservation is publisher-scoped, so a vendor may reuse its own namespace across successor packages (the one deliberate looseness vs the install gate); D3 rule 2 — whitelist namespaces are publishable only by the first-party tier, an addition beyond bare mirroring so the exemption cannot become a shadowing route. Also note §A.2's implied open-side follow-up: namespace must travel on the publish payload (Phase A1, this repo) before the enterprise gate has anything to check.

    The PR stays DRAFT until you rule.


    Generated by Claude Code

  12. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    Contributor

    Maintainer ruling (2026-08-08, via the engine-core PM session): ADR-0048 addendum ACCEPTED as drafted, including the two flagged extensions — D2 (reservation held by the publisher, so same-vendor successor packages may reuse their own namespace; cross-vendor stays a hard publish failure and the install gate still refuses co-install) and D3 rule 2 (whitelist namespaces base/system/sys are publishable only by the first-party tier — exemption from exclusivity is not open season).

    Consequences now live:


    Generated by Claude Code

  13. removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 8, 2026
  14. os-zhuang commented on Aug 8, 2026

    @os-zhuang
    Contributor

    Triage (state-machine repair only): pm:dispatched added — no claim change, no dispatch by this seat.

    This card lost its pm-state at 13:55Z when needs-user-decision came off with the maintainer's acceptance ruling, leaving domain:engine-core with no pm-state — a shape the triage sweep re-selects every round. The true state is dispatched and in flight: claimed 09:26Z by the engine-core seat (session session_01MwoubC3jL271FYt9rGXwxb), deliverable PR #6671 accepted by the maintainer 13:55Z and headed to the merge queue, anchor closes on merge via Fixes. pm:dispatched records exactly that; ownership and follow-through remain entirely with the engine-core seat.

    (The ruling's Phase A1 follow-up card is being filed by this seat separately, routed domain:spec per the ruling's own lane assignment.)

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    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

No one assigned

    Labels

    pm:dispatchedDispatched to a dev agent by /pm-dispatch

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions