Repository navigation
Split the application-security audit domain into remote and local - #1105
Conversation
`application-security` owned both product security specs (127 FAIL IF bullets) and was the catch-all for every unclaimed product directory, so the desktop shells' surfaces went unowned and every canary miss landed there. It becomes two Opus domains: - `remote` owns docs/specs/security-remote.md and claims relay/, remote-lib-common/, deploy/local/, SELF_HOST.md, and the remote trees inside lib/ and vscode-ext/. - `local` owns docs/specs/security-local.md, works a named desktop-shell checklist (Tauri IPC and capabilities, webview CSPs, the updater's trust root, VS Code webview messages, spawned helpers and agent-browser, shell quoting, recovery capture, the built-in Tools), and takes the remainder by subtraction. Every per-domain artifact follows: fragments, AUDIT_FRAGMENTS, the orchestrator's spawn, wait, verdict and merge, the agents JSON in both jobs, the canary's domains and seed headers, the local runner, and security.md's domain table. Ledger keys never named a domain, so no open finding moves. New tests pin per-section ownership, the merge and verdict of every domain's fragment, the public body's rows, security.md's table, the single catch-all, and the canary's domain set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
94f4e8d
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://0001665d.mouseterm.pages.dev |
| Branch Preview URL: | https://audit-domain-split.mouseterm.pages.dev |
dormouse-bot
left a comment
There was a problem hiding this comment.
This split and #1102 will break each other, whichever one merges second, and the conflict goes beyond the Domain: re-heading the description mentions. #1102 replaces the pool-size check in scripts/security-audit-canary.test.mjs with one check per domain:
for (const d of CANARY_DOMAINS) assert.ok(pool.filter((s) => s.domain === d).length >= 3, `${d} has fewer than three seeds`);With this PR's CANARY_DOMAINS = ['supply-chain', 'remote', 'local', 'hosted'], remote has 2 seeds (local-networks-unreadable-pair, relay-mode-fails-open). That check would fail on main as soon as both PRs are in. #1102 also deals CANARY_SEEDS: "6" round-robin across the domains. Over four domains that gives 2/2/1/1, not the two per domain its rationale describes. So whichever PR lands second needs a third remote seed and a fresh look at CANARY_SEEDS (8 would give two per domain again).
# Conflicts: # docs/specs/security-audit.md # scripts/security-audit.test.mjs
The remote domain held two seeds, under the pool's floor of three. The new seed reverses part of #1044: a user-verification raise while a pairing awaits local approval no longer voids the proof it rests on. It is a class seed, beside remote's two rule seeds. CANARY_SEEDS goes from 6 to 8, two whole rounds of the four code domains; six would deal two domains one seed each. A test pins the count to whole rounds the smallest domain can fill, and the local runner's default follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dormouse-bot
left a comment
There was a problem hiding this comment.
The description's merge note is now stale: #1102 is merged into this branch, and this push adds the third remote seed and moves CANARY_SEEDS to 8, so "this PR leaves them alone" and "2 to remote" no longer describe the diff.
application-securityowned both product security specs (127FAIL IFbullets, a reading list of about 50 files) and was the catch-all for every product directory no other domain claimed. Its prompt sent the depth to remote control and left the rest as an open sweep. As a result, the Tauri IPC commands and capabilities, the webview CSPs, the updater's trust root, and agent-browser were named by no prompt, and twelve of the canary pool's thirteen seeds (and their misses) were this domain's. This PR splits it into two Opus domains, so the audit runs five domains and its canary four code domains.Ownership map
remotedocs/specs/security-remote.mdrelay/,remote-lib-common/,deploy/local/,SELF_HOST.md, and insidelib/andvscode-ext/:lib/src/remote/,lib/src/host/remote/,lib/src/host/relay-origin.ts,lib/pocket/,lib/one-time/,vscode-ext/src/burrow*.ts. It readsremote-security-model.md(with its rationale),relay.md,remote-api.md,pocket-app.md,one-time.md,remote-network.md, andSELF_HOST.mdfor context.localdocs/specs/security-local.mdsupply-chain.md,ci-and-secrets.md,hosted.md, andremote.md. Today that is the rest oflib/andvscode-ext/, plusstandalone/,dor/,dor-lib-common/,dor-tools-builtin/,dor-tools-lib/,canopy/,deploy/blyg/,docs/,.impeccable/, and the remaining root files. Its qualitative pass works a named desktop-shell checklist covering Tauri IPC and capabilities, the webview CSPs, the updater's trust root, VS Code webview messages, spawned helpers and their listeners (agent-browser and Chrome, the sidecar, VS Code's PTY host), command construction and quoting for every shell, terminal output turned into typed input (recovery capture), and the built-in Tools. Each item names its files.hosted,supply-chain,ci-and-secretsWork streams:
remotekeepsremote-trust,remote-transport,remote-deploy, andqualitative.localkeepslocal-terminal,local-listeners, andqualitative. Each domain has exactly one qualitative pass.Everything keyed by domain
audit-remote.mdandaudit-local.mdreplaceaudit-application.md. They are added toAUDIT_FRAGMENTSand to the orchestrator's spawn, wait, verdict, and merge, and to the--agentsJSON in the audit and canary jobs.CANARY_DOMAINS,CANARY_FRAGMENTS, the canary orchestrator prompt, and theDomain:headers of the 12application-securityseeds onmainare re-headed (10 tolocal, 2 toremote). The draw is dealt round-robin across the code domains (Audit canary: three seeds per code domain, dealt across the domains #1102), and each must hold at least three seeds, so a thirdremoteseed is added:pairing-approval-outlives-uv-raise, a class seed that reverses part of Reduce Pocket passkey prompts with persisted sessions and Burrow presence windows #1044 (a user-verification raise while a pairing awaits local approval no longer voids the proof it rests on). The pool is nowlocal10,remote3,hosted3,supply-chain3.CANARY_SEEDS: 6 to 8, two whole rounds of the four code domains; 6 would deal two domains one seed each.scripts/security-audit-local.sh canarydefaults to the same count.scripts/security-audit-local.sh, the domain table indocs/specs/security.md, anddocs/specs/security-audit.md(Domains, Canary recall, Future) plus its rationale. The pinned status issue (Publish the security audit's status in a pinned issue, and disclose findings after a fix or 7 days #1108) and the skipped-run report no longer say "four" domains.**Scopeand**Output file, so the new domains flow through without code changes.FAIL IF: now pinned byscripts/security-audit.test.mjs. The test requires exactly one catch-all, and its subtraction must name every other domain's prompt.Cost
The model reads roughly the same amount as before:
security.mdone more time (about 5,500 words), and the two prompts together are about 530 words longer than the old one (2,531 vs 1,998).localnow reads three sections ofdor-browser.mdand two ofdor-cli.mdinstead of both specs whole (about 6,500 fewer words). The checklist's named files take the place of the open sweep.Tests
scripts/security-audit.test.mjs:FAIL IFsection is claimed by exactly one domain (or by the deterministic check alone)audit-remote.mdandaudit-local.mdsecurity.md's table matches each domain's scopescripts/security-audit-canary.test.mjs:CANARY_SEEDSis whole rounds that the smallest domain's pool can fillEach new assertion was checked to go red when its guarded line is reverted: a duplicated or dropped scope claim, a dropped
emit, wait, or verdict entry, the oldAUDIT_FRAGMENTS, the oldsecurity.mdrow, a catch-all that forgetsremote.mdor a second catch-all, the oldCANARY_DOMAINS, a canary prompt that dropslocal, andCANARY_SEEDSdeleted, at 6, or at 16.The new seed applies alone and over the whole pool, and with it applied the
libremote suites (1265 tests),e2e-lint,outbound-lint, andloopback-lintstay green.Locally green:
node --test scripts/security-audit.test.mjs scripts/security-audit-canary.test.mjs(153/153),scripts/github-state-check.test.mjs,pnpm lint:specs(security.mdbudget ratcheted 2850 to 2900 for the added row,security-audit.md4550 to 4600),lint:md,lint:workflows,workflow-lint.test.mjs,e2e-lint,lint:public-docs, andactionlint.Post-merge verification
A canary or audit run on
mainis the only place the split can be measured, so nothing was dispatched from this branch. After merge:security-audit.yamlonmain(gh workflow run security-audit.yaml --ref main). Its decryptedaudit-transcriptshould hold separate, finishedaudit-remote.mdandaudit-local.mdfragments, and the public issue's table (if any) should list both.-f canary=true). The scorecard'sdomainsshould showremoteandlocalscored separately, with no domain left unfinished.Merge note: this changes
.github/audit/and.github/workflows/security-audit.yaml, which are insideworkflow-audit.yaml's window, so the maintainer merges. It is merged up tomainwith #1102 and #1108.🤖 Generated with Claude Code