You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
secrets: a report-only check for stored secret: references that more than one holder names, or that a column other than the one that minted it holds #27721
Follow-up of #27582 (PR #27695), from its contract review record 6507826814 (should-fix S1). Rule level only.
What is missing
#27695 makes a non-system write keep only its own record's secret: reference. Values stored before that change are not re-examined (the PR says so). The existing report, os secret orphans (sys-secret-orphan-report.ts, secret-reference-union.ts), classifies handles that NOTHING names; it does not answer whether a handle is named by more than one holder, or held by a column other than the one whose namespace/key it carries. releaseSecretHandles asks the namespace/key question only when it releases.
Wanted
A report-only extension of the orphan report (no automatic repair, no deletion), listing each sys_secret handle that is named by more than one record/column, or whose holder column is not the column its namespace/key name, with counts and the holder object/field (never the secret, never the handle's plaintext). Note: a predicate update can legitimately share one handle across the rows it matched (#27495); the report must say how it tells that case apart or list it separately. Whether a repair path follows is a later decision.
Read fresh. A report-only extension of os secret orphans: no repair and no deletion. It lists counts and holder object/field, never a secret and never a handle's plaintext.
Claim: PM loop round 1 · 2026-10-29T21:51Z
Session: session_016WV4cw9cC8mhpZX1HgeLg5 (card thread; seat session_016WV4czuTWNgKR22fKv7jia)
Account: os-elon-musk
Branch: claude/project-thread-3kh5oz (the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)
Worktree: objectstack-issue-27721
Domain: domain:server
Seat: domain:server#3
File surface: packages/cli/src/commands/secret/**, packages/cli/src/utils/secret-reference-union.ts (structured holder coordinates only; its ⛔ no-classification header stands), new packages/cli/src/utils/sys-secret-holder-report.ts (the report-only second pass, beside sys-secret-orphan-sweep.ts), packages/services/service-settings/src/sys-secret-orphan-report.ts, content/docs/deployment/cli.mdx (the os secret orphans section only), packages/cli/src/utils/sys-secret-orphan-sweep.test.ts (one fixture literal gains the new required member; no assertion change), and their tests, .changeset/* (amended by the seat on the thread's request before the new file was committed); ⛔ no packages/spec, no governed path (stop on breach; explain in the report)
Container & model: M, mode:thread, model: opus (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate), effort: xhigh
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a report-only extension)
Thread-read: 6508138705
Premise: holds (the orphan report classifies only handles nothing names, per the card; to be re-read on the tree by the dev)
Serial constraints cleared: in-flight #27722 (this seat) works the service-settings credential-handle write doors, not sys-secret-orphan-report.ts; if either needs the other's file, the later one merges main. Report-only: no repair, no deletion; the report never shows a secret or a handle's plaintext; the #27495 predicate-update share is told apart or listed separately (triage).
{
"issue": 27721,
"status": "done",
"branch": "claude/project-thread-3kh5oz",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27792",
"session": "session_016WV4cw9cC8mhpZX1HgeLg5",
"premise_still_valid": true,
"summary": "The orphan report (os secret orphans, report mode) now also lists each sys_secret handle more than one holder record names (shared), each handle at least one holder of which is not the column its (namespace, key) names (misplaced), and, apart from both, a share whose every holder is an object-field row of the handle's own minting column (sharedInOwnColumn: the shape a predicate update writes; stored rows cannot tell it from a reference copied between rows of that column, so it is listed and not judged). Report-only: the section never feeds the deletion plan and repairs nothing; entries carry handle id, (namespace, key), holder count and each holder's object/field/record, never a secret or cipher material. PM mechanism assumption measured: the union did enumerate every naming record, but held each holder only as a printable string, so it cannot see the holder column as data. Obtained by adding a required structured column member (object, field, record, mintedPair) to every SecretReference at the same read (the settings read also selects id); mintedPair is null for the datasource binder, which records the pair its caller passes, so datasource placement is not judged. The classification is a second pass over the union in a new pure module, sys-secret-holder-report.ts (surface amended by the seat); the union module still carries no classification. Public surface: no new flag, no new package export (cli utils are not in the package exports); --json gains one additive top-level key, holders. No shipped consumer or doc treats that JSON as a closed contract: in this repo it is read only by tests via toMatchObject on mode and plan, and the docs call it the same report, machine-readable.",
"tests": "Head 2569bd1ae2. vitest --project integration over sys-secret-holder-report, secret-reference-union, sys-secret-orphan-sweep, orphans.guards, orphans.driver-contract, orphans.journal-mode, data-commands.absent-database: Test Files 7 passed, Tests 136 passed. Fixtures minted by the real producers incl. a REAL predicate update through ObjectQL; the command-level pin runs the real command on SQLite and asserts holders.shared plus no seeded cipher material anywhere in stdout. Whole cli unit project once at 48a9b65dd2 (pre-merge): 349/351 files, 5055 tests passed; the 2 failing files refused because packages/cli itself was unbuilt, and pass after the full build on the final head (2 files, 29 tests). Ablations via scripts/ablation-replace.mjs, each restored (blob == HEAD, git diff HEAD empty); subject resolves through src by relative import, so no dist leg: own-column predicate forced false -> 3 red; placement forced in_place -> 7 red; single-holder skip forced for all -> 6 red; holders key dropped from the command --json -> the command pin red.",
"gates": "node scripts/pm/dispatch-gates.mjs --ran on head 2569bd1ae2: 93 derived, 93 run, 0 NOT-MEASURED, 0 UNRUN (exit 0); all 93 exited 0 (first run at 48a9b65dd2 had 6 exit-3 prerequisite refusals, cleared by git fetch --unshallow and a full pnpm build, then the whole set re-run on the final head). pnpm --filter @objectstack/cli typecheck exit 0 (test-typecheck debt unchanged). ESLint --no-inline-config over the 7 touched TS files exit 0. PR check-runs: in_progress at report time.",
"line_budget": "869 changed lines (+851/-18) over 9 files, under the 3000 threshold; production 325 (+311/-14: holder report 233, union 59, command 39), tests 504, docs 13, changeset 16.",
"files_changed": [
".changeset/27721-secret-orphans-holder-report.md",
"content/docs/deployment/cli.mdx",
"packages/cli/src/commands/secret/orphans.ts",
"packages/cli/src/commands/secret/orphans.driver-contract.test.ts",
"packages/cli/src/utils/secret-reference-union.ts",
"packages/cli/src/utils/secret-reference-union.test.ts",
"packages/cli/src/utils/sys-secret-holder-report.ts",
"packages/cli/src/utils/sys-secret-holder-report.test.ts",
"packages/cli/src/utils/sys-secret-orphan-sweep.test.ts"
],
"deviations": [
"The order asks for pnpm lint; os-dev assigns the repo-wide lint run to CI. Ran ESLint with the repo config over the touched files instead; the repo-wide run is CI's Lint & Repo Gates.",
"File surface widened by the seat before any write: the new sys-secret-holder-report.ts and its test, the os secret orphans section of content/docs/deployment/cli.mdx, and one fixture literal in sys-secret-orphan-sweep.test.ts (required column member; no assertion moved).",
"AGENTS.md says the executor mirrors the card's assignee at pr_create, while os-dev.md and the relay's pr_create note say a dev's create carries no assignees. Followed os-dev and the relay: PR #27792 has no assignee."
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "3 — mcp__github__issue_read x2 (get, get_comments on the card), read-only; plus claude-code-remote subscribe_pr_activity on #27792 (event subscription, not a GitHub write)",
"api_writes": "2 relay strokes — pr_create POST /repos/objectstack-ai/objectstack/pulls (#27792, 13501 bytes read back identical); comment POST /repos/objectstack-ai/objectstack/issues/27721/comments (this report). Plus 2 git pushes (not REST).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — a reference naming a handle that has no sys_secret row is not listed by this report (the card asks about sys_secret handles); the PR's Acceptance notes say so"
]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 真挡得住的权限 | none | P②
Triage: p2 ·
domain:server·area:auth· 2026-10-29T20:56Z⛔ Not a claim.
os secret orphans: no repair and no deletion. It lists counts and holder object/field, never a secret and never a handle's plaintext.security,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia
Claim: PM loop round 1 · 2026-10-29T21:51Z
Session:
session_016WV4cw9cC8mhpZX1HgeLg5(card thread; seatsession_016WV4czuTWNgKR22fKv7jia)Account:
os-elon-muskBranch:
claude/project-thread-3kh5oz(the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)Worktree:
objectstack-issue-27721Domain:
domain:serverSeat:
domain:server#3File surface:
packages/cli/src/commands/secret/**,packages/cli/src/utils/secret-reference-union.ts(structured holder coordinates only; its ⛔ no-classification header stands), newpackages/cli/src/utils/sys-secret-holder-report.ts(the report-only second pass, besidesys-secret-orphan-sweep.ts),packages/services/service-settings/src/sys-secret-orphan-report.ts,content/docs/deployment/cli.mdx(theos secret orphanssection only),packages/cli/src/utils/sys-secret-orphan-sweep.test.ts(one fixture literal gains the new required member; no assertion change), and their tests,.changeset/*(amended by the seat on the thread's request before the new file was committed); ⛔ nopackages/spec, no governed path (stop on breach; explain in the report)Container & model:
M,mode:thread,model: opus (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate),effort: xhighClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (a report-only extension)
Thread-read: 6508138705
Premise: holds (the orphan report classifies only handles nothing names, per the card; to be re-read on the tree by the dev)
Serial constraints cleared: in-flight #27722 (this seat) works the
service-settingscredential-handle write doors, notsys-secret-orphan-report.ts; if either needs the other's file, the later one merges main. Report-only: no repair, no deletion; the report never shows a secret or a handle's plaintext; the #27495 predicate-update share is told apart or listed separately (triage).objectstack-fleet commentedon Oct 29, 2026
os-dev-report
{ "issue": 27721, "status": "done", "branch": "claude/project-thread-3kh5oz", "pr": "https://github.com/objectstack-ai/objectstack/pull/27792", "session": "session_016WV4cw9cC8mhpZX1HgeLg5", "premise_still_valid": true, "summary": "The orphan report (os secret orphans, report mode) now also lists each sys_secret handle more than one holder record names (shared), each handle at least one holder of which is not the column its (namespace, key) names (misplaced), and, apart from both, a share whose every holder is an object-field row of the handle's own minting column (sharedInOwnColumn: the shape a predicate update writes; stored rows cannot tell it from a reference copied between rows of that column, so it is listed and not judged). Report-only: the section never feeds the deletion plan and repairs nothing; entries carry handle id, (namespace, key), holder count and each holder's object/field/record, never a secret or cipher material. PM mechanism assumption measured: the union did enumerate every naming record, but held each holder only as a printable string, so it cannot see the holder column as data. Obtained by adding a required structured column member (object, field, record, mintedPair) to every SecretReference at the same read (the settings read also selects id); mintedPair is null for the datasource binder, which records the pair its caller passes, so datasource placement is not judged. The classification is a second pass over the union in a new pure module, sys-secret-holder-report.ts (surface amended by the seat); the union module still carries no classification. Public surface: no new flag, no new package export (cli utils are not in the package exports); --json gains one additive top-level key, holders. No shipped consumer or doc treats that JSON as a closed contract: in this repo it is read only by tests via toMatchObject on mode and plan, and the docs call it the same report, machine-readable.", "tests": "Head 2569bd1ae2. vitest --project integration over sys-secret-holder-report, secret-reference-union, sys-secret-orphan-sweep, orphans.guards, orphans.driver-contract, orphans.journal-mode, data-commands.absent-database: Test Files 7 passed, Tests 136 passed. Fixtures minted by the real producers incl. a REAL predicate update through ObjectQL; the command-level pin runs the real command on SQLite and asserts holders.shared plus no seeded cipher material anywhere in stdout. Whole cli unit project once at 48a9b65dd2 (pre-merge): 349/351 files, 5055 tests passed; the 2 failing files refused because packages/cli itself was unbuilt, and pass after the full build on the final head (2 files, 29 tests). Ablations via scripts/ablation-replace.mjs, each restored (blob == HEAD, git diff HEAD empty); subject resolves through src by relative import, so no dist leg: own-column predicate forced false -> 3 red; placement forced in_place -> 7 red; single-holder skip forced for all -> 6 red; holders key dropped from the command --json -> the command pin red.", "gates": "node scripts/pm/dispatch-gates.mjs --ran on head 2569bd1ae2: 93 derived, 93 run, 0 NOT-MEASURED, 0 UNRUN (exit 0); all 93 exited 0 (first run at 48a9b65dd2 had 6 exit-3 prerequisite refusals, cleared by git fetch --unshallow and a full pnpm build, then the whole set re-run on the final head). pnpm --filter @objectstack/cli typecheck exit 0 (test-typecheck debt unchanged). ESLint --no-inline-config over the 7 touched TS files exit 0. PR check-runs: in_progress at report time.", "line_budget": "869 changed lines (+851/-18) over 9 files, under the 3000 threshold; production 325 (+311/-14: holder report 233, union 59, command 39), tests 504, docs 13, changeset 16.", "files_changed": [ ".changeset/27721-secret-orphans-holder-report.md", "content/docs/deployment/cli.mdx", "packages/cli/src/commands/secret/orphans.ts", "packages/cli/src/commands/secret/orphans.driver-contract.test.ts", "packages/cli/src/utils/secret-reference-union.ts", "packages/cli/src/utils/secret-reference-union.test.ts", "packages/cli/src/utils/sys-secret-holder-report.ts", "packages/cli/src/utils/sys-secret-holder-report.test.ts", "packages/cli/src/utils/sys-secret-orphan-sweep.test.ts" ], "deviations": [ "The order asks for pnpm lint; os-dev assigns the repo-wide lint run to CI. Ran ESLint with the repo config over the touched files instead; the repo-wide run is CI's Lint & Repo Gates.", "File surface widened by the seat before any write: the new sys-secret-holder-report.ts and its test, the os secret orphans section of content/docs/deployment/cli.mdx, and one fixture literal in sys-secret-orphan-sweep.test.ts (required column member; no assertion moved).", "AGENTS.md says the executor mirrors the card's assignee at pr_create, while os-dev.md and the relay's pr_create note say a dev's create carries no assignees. Followed os-dev and the relay: PR #27792 has no assignee." ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "3 — mcp__github__issue_read x2 (get, get_comments on the card), read-only; plus claude-code-remote subscribe_pr_activity on #27792 (event subscription, not a GitHub write)", "api_writes": "2 relay strokes — pr_create POST /repos/objectstack-ai/objectstack/pulls (#27792, 13501 bytes read back identical); comment POST /repos/objectstack-ai/objectstack/issues/27721/comments (this report). Plus 2 git pushes (not REST).", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed — a reference naming a handle that has no sys_secret row is not listed by this report (the card asks about sys_secret handles); the PR's Acceptance notes say so" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia
ACCEPT → PR #27792 comment 6511097761 · 2026-10-29T23:39Z · ready + auto-merge armed through the relay.