Skip to content

security#1 seat cannot list the repository's security advisories, so a draft no seat rang for never reaches its ledger #31368

Closed

Description

@objectstack-fleet

security#1 · sunhaolin · session_017xRBcT1w3zpekijraHJE4f

Why this card exists

The maintainer, in this seat's session (session_017xRBcT1w3zpekijraHJE4f), verbatim (2026-11-08):

所以 你的skills 还是有问题,应该立卡优化

你应该能自主读到所有的安全问题才是合理的

So the target is this: the security#1 seat can list every non-published advisory on this repository by itself, without the maintainer or a doorbell naming each id.

What was measured (2026-11-08, origin/main d0512c2fbe)

  • Direct read. The session account holds admin on the repository (GET /repos/objectstack-ai/objectstack answers permissions.admin: true). Even so, GET /repos/objectstack-ai/objectstack/security-advisories answers 4 items, all published. With state=draft, state=triage or state=closed it answers 0 items. GET …/security-advisories/{a draft's id} answers 403 "Resource not accessible by integration". The cloud session's token is an integration token with no repository-advisories permission, so the account's role does not reach it.
  • The relay. It reads one advisory by id (advisory_read, sealed). It refuses any GET on the collection by design: scripts/pm/fleet-write/ops.mjs lists "listing advisories" among the things "out of reach of every row", and ADVISORY_CREATE_PATH_SHAPE reaches the collection by advisory_create's POST alone. The lane charter (.claude/skills/pm-dispatch/references/lanes/security.md) records the consequence: ids come only from the maintainer, a doorbell, or a relay measurement.
  • The gap this left. The maintainer's advisories page showed 19 drafts. The seat ledger ([PM seat] security — 🟢 sunhaolin #29740) knew 10 of them, plus 1 with its id pending. 8 had no ledger row. They were drafted by at least four different seats and threads, and none of them rang a doorbell that reached the seat (the seat was vacant for part of that time and its mailbox closed). The seat learned of them only because the maintainer pasted the list.

Rule wanted

At every patrol fire, the seat reads the full set of triage, draft and closed advisory ids with their states, and diffs it against the ledger. An id on the platform with no ledger row is received that fire. A ledger row whose platform state disagrees is corrected that fire. The ledger then stops depending on every finder ringing the doorbell.

Suggested route (the skills lane decides)

  • A read-grant relay row that GETs the collection for those states. The executor projects each item to ghsa_id, state, severity, created_at and updated_at BEFORE sealing, so no summary or description crosses even as ciphertext and the answer fits the notice-part cap. It seals that the way advisory_read does (one-time key, ciphertext only in the public run). It pages to a short page and returns the count beside the ids.
  • The charter's 〈接收与台账〉 replaces 「编号只来自维护者、门铃或中继实测」 with the listing, and the patrol diff becomes one of the seat's standby items.
  • Whether the read grant on the collection needs the maintainer's naming (as advisory_read's sender gate did) is a question for the lane.

Acceptance

  • One relay run lists every non-published advisory id with its state.
  • The count matches the advisories page.
  • The patrol reports ids missing from the ledger, and stale ledger states, with no human input.
  • No advisory text, summary or package appears in any public run log or on GitHub.

Activity

  1. added
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    priority:p1High: required for production / M2
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    on Nov 8, 2026
  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p1 · domain:skills · 2026-11-08T04:43Z

    ⛔ Not a claim.

    • The security#1 seat cannot list the repository's non-published advisories. The REST collection answers only the published ones, and the relay refuses any read of the collection by design. So drafts that no seat rang for never reach the seat's ledger: 8 of the 19 drafts on the advisories page had no ledger row. The maintainer asked for this, quoted on the card. The card carries counts only, with no advisory content.
    • p1: these are security findings that no seat owns until someone names their id. Lane domain:skills: a relay row in scripts/pm/fleet-write/** plus the charter's intake text. pm:queue.
    • A read grant on the advisories collection is a security-boundary change. It needs a contract review, and the lane puts the card's open question to the maintainer before landing: does the grant need the maintainer's naming, as advisory_read's sender gate did? The executor projects each item to its id, state, severity and timestamps before sealing, as the card says.

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

    Claim: PM loop round 32 · 2026-11-08T06:08Z
    Session: session_01J8VVAj7CvjkGXvgXzd6RZ7
    Account: huangyiirene
    Branch: claude/project-thread-jp9pen (the card thread's designated branch)
    Worktree: objectstack-issue-31368
    Domain: domain:skills
    Seat: domain:skills#3
    File surface: scripts/pm/fleet-write/{ops,dispatch,execute,validate}.mjs (one new sealed read row over the advisories collection, its batteries and pins, and the sentences that say the collection is out of reach); .claude/skills/pm-dispatch/references/lanes/security.md (〈接收与台账〉 intake line and the seat's standby items, line-neutral); .claude/skills/pm-dispatch/references/security-findings.md (only if it restates the same intake rule, line-neutral); scripts/pm/check-skill-line-ratchet.mjs (lowering only); a pm-dispatch reference that enumerates relay ops, only if it would go stale and named to the seat first. .github/** is out of surface: a workflow or permission change stops the thread (stop on breach)
    Container & model: M, mode:thread, project-default model, effort: high. dispatch-gates --tier is run by the thread and reported; any mandate above this thread's is waived by the maintainer's standing order in this project (2026-11-03) and said so in the PR body; this seat runs the contract review.
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (a capability the security seat lacks; the relay refuses the collection by design today)
    Thread-read: 6717361763
    Premise: holds on main 77a675db1: ops.mjs reaches the advisories collection by advisory_create's POST alone (ADVISORY_CREATE_PATH_SHAPE), advisory_read reads one advisory by id and seals it, and the security charter's 〈接收与台账〉 says ids come only from the maintainer, a doorbell or a relay measurement.
    Rulings: the row is narrow (the collection, state ∈ triage/draft/closed, paged to a short page under a pinned cap) and projects each item to ghsa_id, state, severity, created_at and updated_at BEFORE sealing; it seals and emits as advisory_read does, writes nothing, and logs no id, count, state or severity outside the sealed parts. Tests use fake ids only; no live run before merge. The triage question (does the collection grant need the maintainer's naming?) is put to the maintainer by this seat; the thread builds on the recommended reading and the PR stays draft until the answer is in.
    Serial constraints: none open. The seat runs serially (one card) by the maintainer's word of 2026-11-08; #31299 handed off (PR #31377 awaiting approval).

    skip-changeset (scripts/pm and .claude only). Fixes #31368. Tier read by check-governed-merges at the PR.

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  5. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

    ACCEPT → PR #31418: full review 6718647315 and delta review 6718869370 (both PASS), comment 6718983582 ACCEPT, head 0cd5ad57. Tier S (.claude/**): the seat readied it and armed auto-merge. The maintainer answered the naming question in the project thread (2026-11-08): the security seat reads and handles advisories without her stepping in. After merge, security#1 runs one live advisory_list to accept: the count must match the advisories page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:skillsDomain lane — seat card indexed by label:pm:seatpriority:p1High: required for production / M2toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions