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
cli: a boot whose data key cannot open the database's sys_secret rows still serves every secret as unset — os start / os dev should pick the key that opens them, or refuse loudly; one-shot commands read only the canonical key file #30042
Filing gate: this is out of scope by ruling in the #29934 order and reported by the dev of PR #30040. The seat's ACCEPT 6628086274 records it as an accepted deviation. ⛔ Not a claim. Triage sets the grade.
Business reason: after PR #30040, os dev and os start share one data-key file, so a project that moves from dev to start keeps its secrets. Three cases remain where the key the boot picks cannot open the project database's sys_secret rows, and every secret then reads back as unset with only a log line:
Reader who acts: domain:server, in packages/cli (internal-crypto-key-file-channel.ts, the one-shot commands) and packages/services/service-settings (resolvePersistedKeyFile, keyFilePath).
Dedupe (open and closed): sys_secret decrypt boot, dev-crypto-key both, failed to decrypt. The nearest is #29934, which closes with PR #30040. New.
What to do
At boot, when resolvePersistedKeyFile answers both-differ (or legacy-only), trial-open one sys_secret row under each candidate. Pick the key that opens it, or refuse to boot with both paths named when neither opens it. Do not pick silently. Grade the refusal against the fail-loud contract of LocalCryptoProvider.
Route the one-shot commands through the same resolvePersistedKeyFile.
Expand ~ in keyFilePath the same way the CLI home resolution does, or document that it is not expanded.
Pins: the case-1 shape (start-only project plus a foreign home key) reads its secrets back, and a key that opens nothing refuses with both paths. Ablate once.
Read fresh. When the boot's data key cannot open the project's sys_secret rows, every secret reads back as unset, with only a log line. Case 1 (a start-only project on a machine that has a home key from another project's os dev) is newly reachable on upgrade by PR fix(cli,service-settings): os dev and os start share one data-key file #30040, which the next release carries. That makes it a regression the release ships, so p1 under 「发版本优先的都p1」.
Availability only: no secret is disclosed and no check is bypassed, so the card stays public.
The PR states the boot refusal against LocalCryptoProvider's fail-loud contract.
Claim: PM loop round 13
Session: session_01WGufzhkoyLG9aL3MMfCgCW (dev: os-dev card thread; seat session_01WGufzibcN9oHa8kDbTTnL5)
Account: os-support-ai
Branch: claude/project-thread-kj4zeo (harness-pinned thread branch; platform exception to claude/issue-<n>-<slug>)
Worktree: the dev thread's own container checkout
Domain: domain:server
Seat: domain:server#6
File surface: packages/services/service-settings/src/local-crypto-provider.ts (resolvePersistedKeyFile, keyFilePath, the file tier), the SettingsService boot read of sys_secret (trial-open), packages/cli/src/utils/internal-crypto-key-file-channel.ts, the one-shot commands (os migrate, os secret rewrap/orphans), pins, and one changeset. ⛔ protocol.ts and engine.ts stay frozen until the #30030 gate lands. On a breach, stop and explain it in the report.
Container & model: M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: the platform's own data-key choice at boot (a start-only project on a machine with a foreign home key reads every secret as unset after #30040) | the seat: #30040 (8d5aab33) made case 1 newly reachable on upgrade | every single-node self-hoster who upgrades with secrets sealed under os start
Thread-read: 6628876432
Premise: holds (the case-1 shape follows from resolvePersistedKeyFile's both-differ branch at 8d5aab33; triage 6628876432; the dev reproduces it on main)
Serial constraints cleared: PR #30040 (#29934) merged as 8d5aab33
Stamp: 2026-11-04T11:07Z
Order: /mnt/project-files/server-orders/30042.md (project files). The declaration is provisional, so the dev measures and declares what the diff actually changes. This is a release-blocker (triage notify 6629019062).
{
"issue": 30042,
"status": "done",
"branch": "claude/project-thread-kj4zeo",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30087",
"session": "session_01WGufzhkoyLG9aL3MMfCgCW",
"premise_still_valid": true,
"summary": "On both-differ the CLI parent no longer picks: it names the canonical file on OS_INTERNAL_CRYPTO_KEY_FILE and the legacy <start home>/dev-crypto-key on one new parent-owned OS_INTERNAL_CRYPTO_KEY_FILE_CANDIDATE. SettingsServicePlugin.start() (objectql started, table readable, before kernel:ready) trial-opens the newest sys_secret row under each key and every CRYPTO_CONTEXT_SCOPES member, writes the winner back, and prints which file and why; neither opens => production throws DataKeyOpensNothingError naming both paths and the remedy (boot fails), dev/test keep canonical with a console.error; no row => canonical. serve's shared provider is deferred so nothing reads the key before the choice; os migrate / os secret rewrap|orphans resolve the same way via resolveExistingDataKey; ~ in OS_HOME/OBJECTSTACK_HOME is expanded in keyFilePath like resolveStartHome. Ciphertext format unchanged, nothing rewrapped, protocol.ts/engine.ts untouched. Deviation from the claim: declared Clause-② yes (narrowing) (new service-settings exports + the new production boot refusal), Metadata-protocol none, patch; changeset carries BREAKING banner, remedy, not-required (no-migration-prescription), and a Supersedes paragraph for #29934's pending changeset.",
"tests": "head ec16e14d: service-settings 1151/1151 (67 files; local-crypto-provider +21, settings-engine-bind-window +2 real LiteKernel); cli unit 5365/5365 (382 files); cli integration dev-start-shared-data-key 6/6 (+3 public-door os start: case 1 reads back and names the file, production refusal names both; budget 40). Closure build 63/63; typecheck service-settings 0, cli 0. Ablations via ablation-replace.mjs + dist rebuild/preflight, restored to HEAD (blob equal, diff empty): A trial forced canonical -> service-settings 12 red + cli 2 red; B production throw disabled -> 3 red; C ~ expansion off -> service-settings 2 red + cli 2 red.",
"gates": "dispatch-gates --commands: 66 derived at ec16e14d, each run serially with exit captured before any pipe. First pass 3 exit 3 (prerequisite, not findings): check-plugin-teardown-shape --self-test (pinned commit absent from shallow clone; fetched 621a4876), check:dual-build-cjs-loads and check:i18n-coverage (dist missing); rerun after -> exit 0. pnpm lint exit 0. --ran: 66 run, 0 NOT-MEASURED, 0 UNRUN. PR check-runs: pending at report time.",
"dogfood_battery": "ec16e14d · os-verify-lock: VERDICT command-exit 0 · held the lock 2074s · Test Files 417 passed | 3 skipped (420) · Tests 3462 passed | 28 skipped (3490) · no failures",
"mcp_calls": "4 — mcp__github__issue_read get, mcp__github__issue_read get_comments x2, mcp__github__pull_request_read get_comments; all reads",
"api_writes": "4 — git push claude/project-thread-kj4zeo x2 (work commits; main merge ec16e14d); relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches -> POST /pulls draft, #30087, body read back identical, no assignees, no labels); post-stamped comment on #30042 (this report)",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": []
}
Landed · 2026-11-04T14:02Z · PR #30087 merged through the queue as f6f663a8. The CONTRACT_REVIEW_TIER review 6631484476 passed, and ACCEPT is 6631494659. pm:dispatched is removed with the close.
What changed: when the canonical and legacy data-key files differ, the boot trial-opens the newest stored sys_secret row under each key, in the serve child with the database open, and uses the key that opens it.
If neither key opens it, a production boot refuses (DataKeyOpensNothingError, naming both paths), and development keeps canonical with a boot error.
The one-shot commands share the choice, and ~ in OS_HOME is expanded.
Patch on @objectstack/cli and @objectstack/service-settings. BREAKING, not-required (no-migration-prescription).
Carried: #30091 (judge the whole fetched page, report a mixed-key database, notice wording, docs, nits).
Activity
objectstack-fleet commentedon Nov 4, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p1 ·
domain:server·pm:queue· 2026-11-04T10:54Z⛔ Not a claim.
sys_secretrows, every secret reads back as unset, with only a log line. Case 1 (a start-only project on a machine that has a home key from another project'sos dev) is newly reachable on upgrade by PR fix(cli,service-settings): os dev and os start share one data-key file #30040, which the next release carries. That makes it a regression the release ships, so p1 under 「发版本优先的都p1」.LocalCryptoProvider's fail-loud contract.Generated by Claude Code
objectstack-fleet commentedon Nov 4, 2026
domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5
Claim: PM loop round 13
Session:
session_01WGufzhkoyLG9aL3MMfCgCW(dev: os-dev card thread; seatsession_01WGufzibcN9oHa8kDbTTnL5)Account:
os-support-aiBranch:
claude/project-thread-kj4zeo(harness-pinned thread branch; platform exception toclaude/issue-<n>-<slug>)Worktree: the dev thread's own container checkout
Domain:
domain:serverSeat:
domain:server#6File surface:
packages/services/service-settings/src/local-crypto-provider.ts(resolvePersistedKeyFile,keyFilePath, the file tier), theSettingsServiceboot read ofsys_secret(trial-open),packages/cli/src/utils/internal-crypto-key-file-channel.ts, the one-shot commands (os migrate,os secret rewrap/orphans), pins, and one changeset. ⛔protocol.tsandengine.tsstay frozen until the #30030 gate lands. On a breach, stop and explain it in the report.Container & model:
M,mode:thread,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
the platform's own data-key choice at boot (a start-only project on a machine with a foreign home key reads every secret as unset after #30040) | the seat: #30040 (8d5aab33) made case 1 newly reachable on upgrade | every single-node self-hoster who upgrades with secrets sealed under os startThread-read: 6628876432
Premise: holds (the case-1 shape follows from
resolvePersistedKeyFile'sboth-differbranch at8d5aab33; triage 6628876432; the dev reproduces it on main)Serial constraints cleared: PR #30040 (#29934) merged as
8d5aab33Stamp: 2026-11-04T11:07Z
/mnt/project-files/server-orders/30042.md(project files). The declaration is provisional, so the dev measures and declares what the diff actually changes. This is a release-blocker (triage notify 6629019062).objectstack-fleet commentedon Nov 4, 2026
domain:server#6 · os-support-ai · session_01WGufzhkoyLG9aL3MMfCgCW
os-dev-report
{ "issue": 30042, "status": "done", "branch": "claude/project-thread-kj4zeo", "pr": "https://github.com/objectstack-ai/objectstack/pull/30087", "session": "session_01WGufzhkoyLG9aL3MMfCgCW", "premise_still_valid": true, "summary": "On both-differ the CLI parent no longer picks: it names the canonical file on OS_INTERNAL_CRYPTO_KEY_FILE and the legacy <start home>/dev-crypto-key on one new parent-owned OS_INTERNAL_CRYPTO_KEY_FILE_CANDIDATE. SettingsServicePlugin.start() (objectql started, table readable, before kernel:ready) trial-opens the newest sys_secret row under each key and every CRYPTO_CONTEXT_SCOPES member, writes the winner back, and prints which file and why; neither opens => production throws DataKeyOpensNothingError naming both paths and the remedy (boot fails), dev/test keep canonical with a console.error; no row => canonical. serve's shared provider is deferred so nothing reads the key before the choice; os migrate / os secret rewrap|orphans resolve the same way via resolveExistingDataKey; ~ in OS_HOME/OBJECTSTACK_HOME is expanded in keyFilePath like resolveStartHome. Ciphertext format unchanged, nothing rewrapped, protocol.ts/engine.ts untouched. Deviation from the claim: declared Clause-② yes (narrowing) (new service-settings exports + the new production boot refusal), Metadata-protocol none, patch; changeset carries BREAKING banner, remedy, not-required (no-migration-prescription), and a Supersedes paragraph for #29934's pending changeset.", "tests": "head ec16e14d: service-settings 1151/1151 (67 files; local-crypto-provider +21, settings-engine-bind-window +2 real LiteKernel); cli unit 5365/5365 (382 files); cli integration dev-start-shared-data-key 6/6 (+3 public-door os start: case 1 reads back and names the file, production refusal names both; budget 40). Closure build 63/63; typecheck service-settings 0, cli 0. Ablations via ablation-replace.mjs + dist rebuild/preflight, restored to HEAD (blob equal, diff empty): A trial forced canonical -> service-settings 12 red + cli 2 red; B production throw disabled -> 3 red; C ~ expansion off -> service-settings 2 red + cli 2 red.", "gates": "dispatch-gates --commands: 66 derived at ec16e14d, each run serially with exit captured before any pipe. First pass 3 exit 3 (prerequisite, not findings): check-plugin-teardown-shape --self-test (pinned commit absent from shallow clone; fetched 621a4876), check:dual-build-cjs-loads and check:i18n-coverage (dist missing); rerun after -> exit 0. pnpm lint exit 0. --ran: 66 run, 0 NOT-MEASURED, 0 UNRUN. PR check-runs: pending at report time.", "dogfood_battery": "ec16e14d · os-verify-lock: VERDICT command-exit 0 · held the lock 2074s · Test Files 417 passed | 3 skipped (420) · Tests 3462 passed | 28 skipped (3490) · no failures", "mcp_calls": "4 — mcp__github__issue_read get, mcp__github__issue_read get_comments x2, mcp__github__pull_request_read get_comments; all reads", "api_writes": "4 — git push claude/project-thread-kj4zeo x2 (work commits; main merge ec16e14d); relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches -> POST /pulls draft, #30087, body read back identical, no assignees, no labels); post-stamped comment on #30042 (this report)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [] }objectstack-fleet commentedon Nov 4, 2026
domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5
Landed · 2026-11-04T14:02Z · PR #30087 merged through the queue as
f6f663a8. TheCONTRACT_REVIEW_TIERreview 6631484476 passed, and ACCEPT is 6631494659.pm:dispatchedis removed with the close.What changed: when the canonical and legacy data-key files differ, the boot trial-opens the newest stored
sys_secretrow under each key, in theservechild with the database open, and uses the key that opens it.DataKeyOpensNothingError, naming both paths), and development keeps canonical with a boot error.~inOS_HOMEis expanded.Patch on
@objectstack/cliand@objectstack/service-settings. BREAKING,not-required (no-migration-prescription).Carried: #30091 (judge the whole fetched page, report a mixed-key database, notice wording, docs, nits).