Skip to content

[PM seat] domain:metadata — ⏳ vacant #6367

Description

@hotlong

This sticker is the sole authoritative registration for the domain:metadata seat. Index = label:pm:seat; entry point #4604. Seat split out of domain:engine-core by maintainer approval 2026-08-07 (PR #6370).

Single-writer rule: only the sitting seat PM edits this body; takeover/handoff = body edit + one audit comment. Liveness is lazy: >24h without output is reclaimable. Read boundary: a takeover reads this body plus only the comments later than its last edit.

Scope

packages/metadata* (incl. metadata-fs, metadata-protocol, metadata-core) and packages/platform-objects.

Red lines: ⛔ metadata format / acceptance-face changes belong to domain:spec (#6017) — the test is "changes the acceptance face", not "touches spec". ObjectQL compilation / query execution / formula / core runtime → domain:engine-core (#6019). The /meta route body lives in packages/restdomain:cli. packages/lint → devx. ⛔ content/docs/releases/ is never touched in a code PR.

Current PM — 🟢 SEATED

os-zhuang · session_012WMpuAfA2KSdDjGF6tm1bH · seated 2026-08-13 ~03:1xZ (audit comment 5275464073). Standing instruction inherited: batch:5 (maintainer 2026-08-12, 「当前任务处理完后,并发降到5」). Maintainer directive this shift: 「任务很多,加速派发」 — answered with parallelism (batch filled to 5), ⛔ not by downgrading model tiers or skipping serialisation.

⛔⛔ READ THIS BEFORE TRUSTING ANY PROSE SUMMARY IN THIS POST

The single most expensive thing measured this shift: the previous incumbent's "decision box" prose list was STALE BY SEVEN OF EIGHT ENTRIES, and it stayed stale through a body edit made hours after the rulings landed. Two of its cards (#7529, #7893) had been ruled by the maintainer on 2026-08-12 at 18:24Z — in one sitting, verbatim 「接受你的全部建议。」 — and moved to pm:queue by the ruling comments themselves. The post kept listing them as open questions. The incoming PM read the post, believed it, and reported a false "decision inbox: 8" plus a non-existent label half-state to the maintainer.

The rule, and it now outranks anything narrative in this file: pm:* labels and the card's own comments are the state. This post is a cache, and caches go stale — including this section. Before treating any card here as open, open the card and read its comments to the end. A ruling arrives as a comment, and no body edit anywhere is obliged to notice it.

⇒ Corollary that cost the most: "the seat post says it needs a decision" is a stale premise exactly like a stale line number. The skill's stale-premise rule says 裁决同罪 — rulings decay like code — and this is that failure in its purest form: a summary of decisions decaying while the decisions themselves were already made.

⚠️ PLATFORM FACTS — measured, ⛔ do not re-derive

  1. Raw GitHub HTTP is 403 in every container of this fleetGH_TOKEN/GITHUB_TOKEN exist but are empty; no gh CLI. Only mcp__github__* works. ⛔ Never write curl … api.github.com into a dispatch order.
    • ⭐ This is why scripts/pm/check-half-states.mjs 401s permanently. That guard is unavailable here, not flaky ⇒ half-state discipline is manual.
  2. ⭐⭐ git push/fetch/ls-remote DO work — only the API layer is blocked. The rescue channel for any cloud container: poke it to push its report on claude/issue-<n>-handover, read with git fetch + git show FETCH_HEAD:.
  3. Subagents CAN reach GitHub (they self-open PRs and self-post reports). ⇒ "the PM opens the PR" is cloud-only. All five cards this round are subagents.
  4. post_turn_summary / status_detail is unreliable — 2 confirmed falsehoods in one shift. ⛔ Never draw a verdict from it.
  5. ⚠️git ls-remote must run with the repo as cwd and always print its control (… 'claude/*' | wc -l, ~203).
  6. ⚠️enable_pr_auto_merge returns an empty-field signaturezero diagnostic value. Confirm by a commit on origin/main or a gh-readonly-queue/* branch hit.
  7. ⚠️list_issues omits assignees even when explicitly requested.A lane listing is not a claim check; open the card.
  8. ⚠️pull_request_read method=get_status shows only legacy commit statuses (Vercel), not check runs. Use get_check_runs.
  9. ⚠️issue_read get_comments on a long card can exceed the tool's output limit (this post's 19 comments = 57KB, rejected whole). Page it (perPage+page) from the tail.
  10. ⚠️list_issues with two labels behaves as OR, not AND — measured this shift ([pm:seat, domain:metadata] returned the whole lane). Intersect locally; ⛔ never read a two-label listing as a filtered set.
  11. ⚠️The API truncates long issue bodiesmeta-field-write-inert: an accepted field PUT never reaches the object — a runtime-created field is stored valid=true and is absent from fields forever #7893's "Decision Required" section lived entirely in the unreturned half, which is why that card read as a fix card. Every dispatch order must make the dev self-check its body for truncation.

The region exemption (authorised 2026-08-12)

declare regions at claim time · merge main before opening the PR · merge again after each sibling lands · let the queue arbitrate

Concurrent-editor cap on a hot file: 3, and only with region-level declarations in the claim comment. The exemption suspends queueing, ⛔ not collision-avoidance.

Worked example from this shift, because the distinction is the whole rule.protocol.ts had four candidates. #8136 (file-wide sweep of error/catch message construction) was dispatched; #7654 was dispatched alongside it as second concurrent editor, because its region is the getMetaItemsread merge — genuinely disjoint. #7748 (audit-write sites, incl. assertLockAllowsWrite's deny path) and #8184 (saveMetaItem's scoped-kernel refusal branch) were held, because both sit inside the refusal paths #8136 is rewriting. Region ≠ file, and "the file is busy" is the wrong test in both directions.

Model tiering — two clauses with NO downward discretion

  1. ⛔ Any card touching .claude/skills/pm-dispatch/**claude-fable-5, filed and dispatched, never PM-edited.
  2. ⛔ Any card that changes contract accept/reject behaviour or widens the public surface (domain:spec semantic lane) ⇒ claude-fable-5.

Otherwise sonnet for mechanical cards decided by the gate farm, opus for design judgement; when unsure go up. ⚠️ A directive to go faster is answered with parallelism, not a cheaper tier.

Ledger — 23 landed across the previous term (both queued PRs drained)

cardPRcommit
#7728#79204c5e80e
#7774#79317372d46
#7856#7992c7e7900 — 1973-file corpus, 0 hashes changed
#7932#799340e8653
#7780#79953da3da5
#7556#8015e3c8ed0
#8027#8045fa6dd59
#80469b959f3
#8003#81515247fda811
#7656#81798eb5d8b9b5
#8038#8255a6cd2c152f
#7736#82570e1f6679b4
#8037#82583a27c46edb⚠️Part of, card stays open
#7682#8185ebf7d98Part of; closure action executed, card closed completed
#8031#82549b2d720Fixes, card auto-closed

The inherited Part of closure action on #7682 is discharged (comment 5275468337): label write, delivered/remaining/owner recorded, card closed completed — its whole residue is #8146 and #8184, both open and tracked, so re-queueing would have put a card back in the pool whose content is tracked twice elsewhere.

In flight — 5 cards, batch:5 cap reached, file-disjoint by construction

cardregionmodelnote
#8136protocol.ts — error/catch message constructionopussecurity; re-dispatched after a stale-claim reclaim
#7654protocol.tsgetMetaItemsread mergeopus2nd concurrent editor under the region exemption; Part of (bridge half is domain:cli)
#8146sys-metadata-repository.tsopuspremise-gated — if the package-less hatch write also binds into a package, NARROW preserves nothing ⇒ fork back to maintainer
#8154metadata-diagnostics.tsopussecurity; deliverable is the generic per-type redaction hook
#7934platform-objects / metadata-coreopusblocker cleared — validateManagedApiMethods verified on origin/main

Held behind #8136 (hold notes posted, release = when #8136 lands): #7748, #8184. Both stay pm:queue/unassigned — ⛔ deliberately notpm:blocked: a serialisation hold is not an upstream dependency.

⛔ Maintainer decision box — 1 card (label-verified, ⛔ not prose)

needs-user-decision in this lane resolves to exactly one card: #8284. Everything the previous post listed here was already ruled, on hold, blocked, or not in this lane. Verified against the label set, not against any summary.

Adjacent, and NOT in the decision box — do not re-escalate these:

⭐ RULED AND DISPATCHABLE — front of next round's queue

Both ruled by the maintainer 2026-08-12 18:24Z in one sitting (verbatim 「接受你的全部建议。」), both correctly sitting in pm:queue. Both are instances of one standing principle adopted in that same ruling, which also covers #8010 / #7912:

If the platform cannot honour a declaration, refuse it at the latest checkpoint that can see the whole picture (publish), name the offending key path, and never answer 200.

finding — 9

#7216 · #7860 · #8100 · #8169 · #8184 (also held) · #8268 · #8278 · #8284 (also decision) · #8285. A findings-triage round is overdue#7216 is the oldest and has survived several rounds.

#8268 argues for ruling the CLASS, not a fourth instance: three materialization stamps have diverged on one seam one at a time — #6562 (system columns) → #8038 (__search) → #8268 (nameField). ⚠️Read #8268, #8284 and #8037 together before assigning any of themnameField, label, pluralLabel, description are all scalars in the same last-writer-wins class reached by two different mechanisms. Fixing one in isolation is how this lane got three cards out of one seam, twice.

⛔ Not this seat's

#7850 (drivers/services/objectql) · #7643 (objectui) · #7020 (os-help) · #6504 (assigned os-zhuang by a different session — the account is shared across seats, the session ID is the discriminator) · #4716 (corpus precondition unmet — but see #7529 above, it is that card's named carrier). ⚠️#7894 needs re-examining rather than inheriting its "not mine (packages/spec)" tag: #7893's ruling names it as the same door, to be closed in the same pass or explicitly deferred. ⚠️ All of these still carry domain:metadata; mislabels are triage's to correct — this seat ⛔ does not change domain:*, it reports.

⛔ Cloud containers

All four archived, each only after its text reached GitHub. ⭐ Read needs_action, not just status_category, before archiving — a container was archived while its needs_action named an unfiled driver-path bug; it survives only as the incomplete lead #8100.

Inherited process gap, recorded by the incumbent who caused it: when opening a PR on a 403-blocked dev's behalf, get its intended PR body FIRST via the .os-handover channel, and treat draft as the default until the dev says otherwise. Reconstructing a PR body from a branch silently discards the author's merge conditions — it happened twice in one shift.

Handover branches to delete once consumed:claude/issue-7893-handover, claude/issue-8038-handover, claude/issue-8031-handover.

Standing commitments

  • Dispatch briefs are three-partitioned — ruling (not re-litigable) / PM mechanism assumption (falsifiable, measure it) / suggested route (optional).
  • Gate lists are leads, not specs — PM takes the reading with node scripts/pm/dispatch-gates.mjs; the order tells the dev to re-run it against their actual diff.
  • Stale-premise checks cover rulings, not just code — see the ⛔⛔ section at the top of this post for the shift where that was proved twice over.
  • Fixes #n vs Part of #n is a closure decision — label write and delivered/remaining/owner comment in the same action.
  • STOP / needs_decision is a design exit, not rework.

Notes

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:metadatapm:seatPM seat registry issue - single-writer body, index = this label

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions