diff --git a/docs/decisions/0002-xmpp-sasl-validation.md b/docs/decisions/0002-xmpp-sasl-validation.md index 5b50d30..00f6783 100644 --- a/docs/decisions/0002-xmpp-sasl-validation.md +++ b/docs/decisions/0002-xmpp-sasl-validation.md @@ -1,10 +1,10 @@ # ADR 0002-SASL: Fail-closed SCRAM server-final experiment -- Status: proposed; requires independent security review of S00-017. +- Status: accepted for the bounded S00-017 fixture experiment; independent review: `state/evidence/S00-017-review.md`. - Task: S00-017, remediation for S00-003. - Date: 2026-10-15. - Owner: auto-protocol-599343cd9e3f (protocol). -- Reviewer: assigned security role, decision pending. +- Reviewer: auto-security-9ab954f6e021 (security), 2026-10-15. - Requirements: ACC-004, NET-003, NET-004; accepted ADR 0000/0001 preserved. ## Question and bounded result @@ -110,3 +110,15 @@ a fresh S00-003 executor to evaluate this approach in its own experiment; it doe not implement that original task or change the accepted stack/shared contracts. Any required broader policy/interface or vendor replacement is a separately scoped plan decision. Coordinator owns transition commits and fresh processes. + +## Independent acceptance + +Security reviewer auto-security-9ab954f6e021 independently repeated fresh-cache +npm ci and all 44 integrated tests on Node 24.21.0/npm 11.19.0. Exact installed +pins, all eight MIT notices, HTTPS/integrity entries, shipped public extension +APIs and unchanged vendor files were verified. RFC proofs/finals match primary +examples; forged/missing/premature final cannot authenticate in the demonstrated +handler. make check passed 72 tooling tests. This bounded experiment is accepted; +Stanza selection, complete mechanism policy, browser crypto/build, WSS/server +interoperability, parser certification, timeout and constant-time assurance remain +unverified. S00-003 must evaluate integration in a new assigned session. diff --git a/planning/TASK_MATRIX.md b/planning/TASK_MATRIX.md index 55cd1b1..13ac91b 100644 --- a/planning/TASK_MATRIX.md +++ b/planning/TASK_MATRIX.md @@ -1,12 +1,12 @@ # Матрица задач -Generated; state revision **40**. Canonical status: state/tasks.json. +Generated; state revision **41**. Canonical status: state/tasks.json. | ID | Этап | Оператор | Reviewer | Статус | Owner | Зависимости | Задача | | --- | --- | --- | --- | --- | --- | --- | --- | | [S00-001](tasks/S00-001.md) | S00 | orchestrator | security | done | auto-orchestrator-48aab142ecde | | Утвердить Web-профиль | | [S00-002](tasks/S00-002.md) | S00 | orchestrator | security | done | auto-orchestrator-68a05c587e33 | S00-001, S00-011, S00-012 | Выбрать framework и build runtime | -| [S00-003](tasks/S00-003.md) | S00 | protocol | qa | blocked | auto-protocol-826aa6bc12ef | S00-001, S00-002, S00-017 | Проверить XMPP WSS/auth библиотеку | +| [S00-003](tasks/S00-003.md) | S00 | protocol | qa | todo | | S00-001, S00-002, S00-017 | Проверить XMPP WSS/auth библиотеку | | [S00-004](tasks/S00-004.md) | S00 | crypto | security | todo | | S00-001, S00-002 | Проверить browser OMEMO backend | | [S00-005](tasks/S00-005.md) | S00 | storage | qa | todo | | S00-002 | Выбрать IndexedDB wrapper и migration policy | | [S00-006](tasks/S00-006.md) | S00 | orchestrator | security | todo | | S00-002 | Зафиксировать browser/reference matrix | @@ -19,7 +19,7 @@ Generated; state revision **40**. Canonical status: state/tasks.json. | [S00-014](tasks/S00-014.md) | S00 | ci-cd | qa | done | auto-ci-cd-14343249da62 | S00-001, S00-011, S00-013 | Fix repeated runner cleanup after a submitted parent is reaped | | [S00-015](tasks/S00-015.md) | S00 | ci-cd | qa | done | auto-ci-cd-84e209103f24 | S00-001, S00-011, S00-013, S00-014, S00-016 | Устранить прерывание: Fix runner prompt delivery after partial stdin timeout | | [S00-016](tasks/S00-016.md) | S00 | ci-cd | qa | done | auto-ci-cd-351a0cbbabef | S00-001, S00-011, S00-013, S00-014 | Restore reviewer model availability after provider capacity failure | -| [S00-017](tasks/S00-017.md) | S00 | protocol | security | review | auto-protocol-599343cd9e3f | S00-001, S00-002 | Establish fail-closed SCRAM server-final validation | +| [S00-017](tasks/S00-017.md) | S00 | protocol | security | done | auto-protocol-599343cd9e3f | S00-001, S00-002 | Establish fail-closed SCRAM server-final validation | | [S00-010](tasks/S00-010.md) | S00 | qa | orchestrator | todo | | S00-001, S00-002, S00-003, S00-004, S00-005, S00-006, S00-007, S00-008, S00-009 | Gate: Профиль и проверка стека | | [S01-001](tasks/S01-001.md) | S01 | orchestrator | security | todo | | S00-010 | Описать identity/model contracts | | [S01-002](tasks/S01-002.md) | S01 | orchestrator | security | todo | | S00-010, S01-001 | Описать async account context | diff --git a/planning/stages/S00.md b/planning/stages/S00.md index 819a762..ea00d50 100644 --- a/planning/stages/S00.md +++ b/planning/stages/S00.md @@ -8,7 +8,7 @@ - [S00-001](../tasks/S00-001.md): Утвердить Web-профиль — orchestrator; done. - [S00-002](../tasks/S00-002.md): Выбрать framework и build runtime — orchestrator; done. -- [S00-003](../tasks/S00-003.md): Проверить XMPP WSS/auth библиотеку — protocol; blocked. +- [S00-003](../tasks/S00-003.md): Проверить XMPP WSS/auth библиотеку — protocol; todo. - [S00-004](../tasks/S00-004.md): Проверить browser OMEMO backend — crypto; todo. - [S00-005](../tasks/S00-005.md): Выбрать IndexedDB wrapper и migration policy — storage; todo. - [S00-006](../tasks/S00-006.md): Зафиксировать browser/reference matrix — orchestrator; todo. @@ -21,7 +21,7 @@ - [S00-014](../tasks/S00-014.md): Fix repeated runner cleanup after a submitted parent is reaped — ci-cd; done. - [S00-015](../tasks/S00-015.md): Устранить прерывание: Fix runner prompt delivery after partial stdin timeout — ci-cd; done. - [S00-016](../tasks/S00-016.md): Restore reviewer model availability after provider capacity failure — ci-cd; done. -- [S00-017](../tasks/S00-017.md): Establish fail-closed SCRAM server-final validation — protocol; review. +- [S00-017](../tasks/S00-017.md): Establish fail-closed SCRAM server-final validation — protocol; done. - [S00-010](../tasks/S00-010.md): Gate: Профиль и проверка стека — qa; todo. ## Граница этапа diff --git a/planning/task_matrix.csv b/planning/task_matrix.csv index dd330e8..ec39c12 100644 --- a/planning/task_matrix.csv +++ b/planning/task_matrix.csv @@ -1,7 +1,7 @@ id,stage,operator,reviewer,status,owner,depends_on,title S00-001,S00,orchestrator,security,done,auto-orchestrator-48aab142ecde,,Утвердить Web-профиль S00-002,S00,orchestrator,security,done,auto-orchestrator-68a05c587e33,"S00-001, S00-011, S00-012",Выбрать framework и build runtime -S00-003,S00,protocol,qa,blocked,auto-protocol-826aa6bc12ef,"S00-001, S00-002, S00-017",Проверить XMPP WSS/auth библиотеку +S00-003,S00,protocol,qa,todo,,"S00-001, S00-002, S00-017",Проверить XMPP WSS/auth библиотеку S00-004,S00,crypto,security,todo,,"S00-001, S00-002",Проверить browser OMEMO backend S00-005,S00,storage,qa,todo,,S00-002,Выбрать IndexedDB wrapper и migration policy S00-006,S00,orchestrator,security,todo,,S00-002,Зафиксировать browser/reference matrix @@ -14,7 +14,7 @@ S00-013,S00,ci-cd,qa,done,auto-ci-cd-5f68f03dd33b,"S00-001, S00-011",Bound overs S00-014,S00,ci-cd,qa,done,auto-ci-cd-14343249da62,"S00-001, S00-011, S00-013",Fix repeated runner cleanup after a submitted parent is reaped S00-015,S00,ci-cd,qa,done,auto-ci-cd-84e209103f24,"S00-001, S00-011, S00-013, S00-014, S00-016",Устранить прерывание: Fix runner prompt delivery after partial stdin timeout S00-016,S00,ci-cd,qa,done,auto-ci-cd-351a0cbbabef,"S00-001, S00-011, S00-013, S00-014",Restore reviewer model availability after provider capacity failure -S00-017,S00,protocol,security,review,auto-protocol-599343cd9e3f,"S00-001, S00-002",Establish fail-closed SCRAM server-final validation +S00-017,S00,protocol,security,done,auto-protocol-599343cd9e3f,"S00-001, S00-002",Establish fail-closed SCRAM server-final validation S00-010,S00,qa,orchestrator,todo,,"S00-001, S00-002, S00-003, S00-004, S00-005, S00-006, S00-007, S00-008, S00-009",Gate: Профиль и проверка стека S01-001,S01,orchestrator,security,todo,,S00-010,Описать identity/model contracts S01-002,S01,orchestrator,security,todo,,"S00-010, S01-001",Описать async account context diff --git a/state/commit_messages/auto-security-9ab954f6e021.txt b/state/commit_messages/auto-security-9ab954f6e021.txt new file mode 100644 index 0000000..20e6ce1 --- /dev/null +++ b/state/commit_messages/auto-security-9ab954f6e021.txt @@ -0,0 +1,4 @@ +Approve fail-closed SCRAM validation after independent integration checks + +Changes: Accept the bounded S00-017 fixture experiment and ADR; record independent security review and handoff with remaining browser, WSS, mechanism-policy and timing limits. +Validation: Fresh-cache npm ci and npm test passed on Node 24.21.0/npm 11.19.0 with 44 integrated tests. Verify exact installed pins, eight MIT notices, HTTPS/integrity and unchanged vendor files. make check passed 72 tooling tests; inspect executor scope/message and review metadata whitespace. No browser/server interoperability or constant-time assurance claimed. diff --git a/state/evidence/S00-017-review.md b/state/evidence/S00-017-review.md new file mode 100644 index 0000000..a81dcd7 --- /dev/null +++ b/state/evidence/S00-017-review.md @@ -0,0 +1,34 @@ +# S00-017 independent security review + +Reviewer: auto-security-9ab954f6e021 (security). Executor: auto-protocol-599343cd9e3f. +Date: 2026-10-15. Decision: approve the isolated fail-closed SCRAM experiment and bounded ADR. + +Input: assigned card/packet, master/startup/role/workflow documents, required TESTING, protocol role, ADR registry and S00-017 blocker; exact ACC-004/NET-003/NET-004; accepted scope/stack ADRs and direct dependency evidence/reviews/handoffs; S00-003 blocker evidence and previous handoffs. Output: independent decision, accepted ADR metadata and review handoff. No shared S01 contract is introduced. + +## Findings + +Implementation commit 493fbaebe71752677da43aef1e15efbf0343adb4 and executor message match the actual isolated plugin, tests, pins/notices and limitations. Commit path list and workflow diff examined; current source files read with clean working tree before review metadata. Source changes are confined to the card's experiment and ADR; the remaining paths are workflow/generated metadata. Parent exploratory sources, specs, shared contracts and planning definitions are unchanged. + +The real Client/XML registry/feature dispatcher drives the tests; only transport/send effects are captured. Verifier tracing invokes the original processSuccess/finalize methods, never fabricates crypto results. Installed SCRAM computes proof/serverSignature using existing library composition and Node crypto, then compares the supplied verifier in finalize. Both exact RFC SHA-1/SHA-256 client proofs and finals pass. Stock missing/forged premature success is reproduced as insecure behavior. Replacement rejects those cases plus missing/forged/error/conflicting/duplicate/malformed/oversized finals after proof without success, authenticated flags or restart. Fail removes listeners, clears flags, emits failure and disconnects once; replay cannot revive a closed attempt. Reset cancels credentials/proof-send continuation; duplicate/out-of-order and rejected send/credential paths are covered. + +Public shipped Client.use and registerFeature declarations and implementation support replacement before negotiation. Handler lookup is by name; duplicated order entry does not execute another handler after restart/disconnect. Installing late or alongside another replacement remains prohibited by the README. Non-PLUS SHA-256 is preferred to SHA-1; PLUS/plaintext-only offers fail and TLS binding is not invented. No authored crypto primitives, vendor patch, persistence/cache emission, real credentials, network authentication, peer/crypto log output or certificate/CORS bypass found. Public RFC credentials and example.invalid JID remain fixture data. + +Strict additional-data syntax and bounds prevent library directive parsing from ignoring conflicting final attributes. They are deliberately restricted experiment policy, not full parser/resource certification. Only success additional-data and extension-free non-PLUS SHA-1/256 are accepted. Complete NET-003 mechanism selection, SHA-512, extensions/separate-final layout and actual WSS remain S00-003. Constant-time verification, browser crypto/RNG/build, advisory/provenance clearance, independent server/client interoperability and timeout policy were not tested or accepted. Node/npm pins and lock integrity establish repeatability, not adversary-resistant metadata authentication or supply-chain clearance. No acceptance defect or review blocker found within this fixture scope. + +## Actual independent checks + +- python3 scripts/tasks.py resume --agent auto-security-9ab954f6e021; show S00-017; packet S00-017 --agent auto-security-9ab954f6e021: exit 0 each. Review status, distinct executor and done prerequisites confirmed; no claim. +- Read-only git log --all --grep='^S00-017:' --format='%h %s', git show 493fbae --stat and workflow sections, git status --short: exit 0; initially clean tree. Source/test/manifest/lock/notice/API reads completed. +- PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH node --version / npm --version: exit 0, v24.21.0 / 11.19.0. Reused the previously accepted isolated runtime; no new archive verification claimed. +- Same PATH npm ci --prefix experiments/0002-xmpp-library/sasl-validation --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-sasl-review-9ab954f6e021 --fetch-retries=0 --fetch-timeout=15000: exit 0; new reviewer cache, eight packages, strict HTTPS/engines retained and scripts disabled. +- Same PATH npm test --prefix experiments/0002-xmpp-library/sasl-validation: exit 0; 44 passed, zero failed/skipped/cancelled, duration 988.838125 ms. +- Inline Python manifest/lock/installed-license assertions: exit 0; all eight installed exact versions and MIT licenses agree, HTTPS registry/SHA512 entries retained, installed license texts present in notices and inventory complete. Client.js, plugins/sasl.js, plugins/features.js and lib/sasl/index.js byte-match parent installed original files. +- SHA256 package-lock.json: 6413668910ec921d7871225f22fe2753ceaf32c6c185cda6d0a5fd0e27643514; validated-sasl.mjs: 196b16baa16fea051dc6502bae11f80ebea02f87634d90ea72778ee14557a3b9. Match executor evidence. +- make check: exit 0; 282 tasks, 22 stages, 221 requirements, 211 allocated Web requirements, revision 40; 72 tooling tests in 18.231 s. Foundation integrity, not messenger readiness. +- git diff --check before review metadata: exit 0. Final metadata diff/whitespace checked separately before approval. + +Primary sources independently opened through web tools: [RFC 5802 §5](https://www.rfc-editor.org/rfc/rfc5802.html#section-5) and [RFC 7677 §3](https://www.rfc-editor.org/rfc/rfc7677.html#section-3). Web find did not locate fixture strings; canonical .txt sources fetched with curl --fail --silent --show-error and exchange sections displayed through rg, exit 0, confirmed exact transcript values. Shipped version-pinned API/source supplies library facts. + +Exploratory guessed paths 0000-web-scope.md, lib/sasl/scram.js and platform/node.js were absent; actual 0000-scope.md, lib/sasl/index.js and platform/node/index.js were located/read. These failed exploratory reads are not passed checks or missing required artifacts. + +Reviewer changes only ADR acceptance metadata/paragraph, review evidence, handoff and mandatory commit message plus CLI-generated transition. Coordinator must commit the review before the next session; this reviewer ends after approve and does not continue S00-003. diff --git a/state/handoffs/S00-017.md b/state/handoffs/S00-017.md index 9eb55fe..66cf15b 100644 --- a/state/handoffs/S00-017.md +++ b/state/handoffs/S00-017.md @@ -29,3 +29,12 @@ rejection and no timeout policy. No constant-time/browser-crypto/advisory audit. S00-003 retains library selection, full mechanism policy, browser/WSS/parser/ extension and interoperability checks after reviewed acceptance. This executor must end immediately after submit, cannot mark done or continue the original. + +Independent security review: auto-security-9ab954f6e021, 2026-10-15. +Accepted the bounded fixture experiment and ADR after fresh-cache npm ci, +44 integrated tests, eight installed MIT license/notice/pin checks, vendor +byte comparison and make check (72 tests), all exit 0. Report: +state/evidence/S00-017-review.md. No blocker or acceptance defect found. +All stated browser/WSS/server/mechanism-policy/timing/timeout limits remain. +Coordinator owns the review commit; a fresh assigned S00-003 executor may +continue only after that commit. Reviewer exits immediately after approve. diff --git a/state/tasks.json b/state/tasks.json index 4db221a..204317d 100644 --- a/state/tasks.json +++ b/state/tasks.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "revision": 40, + "revision": 41, "tasks": { "S00-001": { "status": "done", @@ -32,17 +32,17 @@ "completed_at": "2026-10-14T19:06:23+00:00" }, "S00-003": { - "status": "blocked", - "owner": "auto-protocol-826aa6bc12ef", + "status": "todo", + "owner": null, "started_at": "2026-10-14T19:06:24+00:00", - "reason": "StanzaJS 12.22.1 SASL feature accepts missing/forged server-final without processSuccess/finalize, including success before challenge/proof. Safe SCRAM cannot be attested by S00-003 until this authentication boundary has a reviewed solution.", - "updated_at": "2026-10-14T19:09:23+00:00", - "blocked_by": [ - "S00-017" - ], + "reason": null, + "updated_at": "2026-10-14T19:20:57+00:00", + "blocked_by": [], "resume_status": "in_progress", "blocker_report": "state/blockers/S00-017.md", - "handoff": "state/handoffs/S00-003.md" + "handoff": "state/handoffs/S00-003.md", + "previous_owner": "auto-protocol-826aa6bc12ef", + "resumed_after_blocker": true }, "S00-004": { "status": "todo", @@ -1221,14 +1221,17 @@ "completed_at": "2026-10-14T18:58:04+00:00" }, "S00-017": { - "status": "review", + "status": "done", "owner": "auto-protocol-599343cd9e3f", "external_wait": false, "reason": null, "started_at": "2026-10-14T19:09:24+00:00", - "updated_at": "2026-10-14T19:17:46+00:00", + "updated_at": "2026-10-14T19:20:57+00:00", "evidence": "state/evidence/S00-017-auto-protocol-599343cd9e3f.md", - "handoff": "state/handoffs/S00-017.md" + "handoff": "state/handoffs/S00-017.md", + "reviewer": "auto-security-9ab954f6e021", + "review_evidence": "state/evidence/S00-017-review.md", + "completed_at": "2026-10-14T19:20:57+00:00" } }, "events": [ @@ -1743,6 +1746,27 @@ "to": "review", "reason": null, "evidence": "state/evidence/S00-017-auto-protocol-599343cd9e3f.md" + }, + { + "revision": 41, + "at": "2026-10-14T19:20:57+00:00", + "action": "auto-unblock", + "task": "S00-003", + "resolved_by": "S00-017", + "to": "todo", + "fresh_agent_required": true + }, + { + "revision": 41, + "at": "2026-10-14T19:20:57+00:00", + "action": "approve", + "task": "S00-017", + "agent": "auto-security-9ab954f6e021", + "role": "security", + "from": "review", + "to": "done", + "reason": null, + "evidence": "state/evidence/S00-017-review.md" } ], "retired_agents": [