From 74e1fd87d96114b72418227aecac2d35b6f7f849 Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Thu, 15 Oct 2026 02:35:56 +0700 Subject: [PATCH] S00-018: Approve bounded XML ingress after independent framing checks Changes: Accept the isolated S00-018 ingress experiment and bounded ADR; record independent security findings and review handoff. Preserve all browser, live WSS, interoperability and production resource limitations. Validation: Fresh-cache npm ci and all 55 integrated tests passed on Node 24.21.0/npm 11.19.0; six additional adversarial documents rejected before real JXT.parse with stale callback/fresh attempt checks. Verified ten dependency licenses/integrities, 340 unchanged Stanza files, upstream saxes license bytes and matching digests. Stock defects reproduced; make check passed 72 tooling tests. Initial getter-only tracing attempt failed and is recorded separately. Scope/whitespace inspected; no browser or live WSS test. Task: S00-018 Agent: auto-security-64dc2d9fa232 Role: security Action: review Status: done Task title: Validate bounded standalone XML ingress for the XMPP candidate --- docs/decisions/0002-xmpp-parser-validation.md | 20 ++- planning/TASK_MATRIX.md | 6 +- planning/stages/S00.md | 4 +- planning/task_matrix.csv | 4 +- .../auto-security-64dc2d9fa232.txt | 4 + state/evidence/S00-018-review.md | 123 ++++++++++++++++++ state/handoffs/S00-018.md | 12 ++ state/tasks.json | 46 +++++-- 8 files changed, 198 insertions(+), 21 deletions(-) create mode 100644 state/commit_messages/auto-security-64dc2d9fa232.txt create mode 100644 state/evidence/S00-018-review.md diff --git a/docs/decisions/0002-xmpp-parser-validation.md b/docs/decisions/0002-xmpp-parser-validation.md index 3042883..a7a6c0e 100644 --- a/docs/decisions/0002-xmpp-parser-validation.md +++ b/docs/decisions/0002-xmpp-parser-validation.md @@ -1,10 +1,10 @@ # ADR 0002 parser remediation: bounded standalone XML ingress -- Status: proposed; independent security review pending. +- Status: accepted for the bounded S00-018 fixture experiment; independent review: `state/evidence/S00-018-review.md`. - Task: S00-018 (remediation of S00-003). - Date: 2026-10-15. - Owner: auto-protocol-89fe6563092c (protocol). -- Reviewer: not yet assigned. +- Reviewer: auto-security-64dc2d9fa232 (security), 2026-10-15. Input: reviewed scope/stack/SASL ADRs, S00-003 parser blocker and bounded probe, shipped Stanza parser/transport declarations and RFC 7395. Output: one isolated @@ -98,3 +98,19 @@ original selection/product work; existing accepted SASL experiment is unchanged. Independent security reviewer must inspect enforcement order/API integration, repeat clean install/tests/license/vendor checks and record acceptance before this ADR or S00-018 is accepted. Coordinator alone commits/launches further work. + + +## Independent acceptance + +Security reviewer auto-security-64dc2d9fa232 independently repeated fresh-cache +npm ci and all 55 integrated tests on Node 24.21.0/npm 11.19.0. Ten exact +installed dependency licenses/integrities and all 340 unchanged Stanza files +were checked; the preserved saxes license byte-matches the versioned upstream +HTTPS source. Additional six adversarial inputs rejected before traced real +JXT.parse, all four stale socket callbacks left fresh attempts unaffected, and +fresh attempts imported the exact aggregate-boundary body. make check passed +72 tooling tests. Public shipped constructor/Transport APIs and enforcement +order were inspected. The bounded experiment is accepted; every browser, +WSS/interoperability, aggregate resource, sequencing and production-policy +limitation above remains. Report records commands and the failed initial tracing +attempt. Coordinator owns the review commit and subsequent fresh assignment. diff --git a/planning/TASK_MATRIX.md b/planning/TASK_MATRIX.md index 0ae2aae..a9dd5e6 100644 --- a/planning/TASK_MATRIX.md +++ b/planning/TASK_MATRIX.md @@ -1,12 +1,12 @@ # Матрица задач -Generated; state revision **45**. Canonical status: state/tasks.json. +Generated; state revision **46**. 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-902594b44429 | S00-001, S00-002, S00-017, S00-018 | Проверить XMPP WSS/auth библиотеку | +| [S00-003](tasks/S00-003.md) | S00 | protocol | qa | todo | | S00-001, S00-002, S00-017, S00-018 | Проверить 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 | @@ -20,7 +20,7 @@ Generated; state revision **45**. Canonical status: state/tasks.json. | [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 | done | auto-protocol-599343cd9e3f | S00-001, S00-002 | Establish fail-closed SCRAM server-final validation | -| [S00-018](tasks/S00-018.md) | S00 | protocol | security | review | auto-protocol-89fe6563092c | S00-001, S00-002, S00-017 | Validate bounded standalone XML ingress for the XMPP candidate | +| [S00-018](tasks/S00-018.md) | S00 | protocol | security | done | auto-protocol-89fe6563092c | S00-001, S00-002, S00-017 | Validate bounded standalone XML ingress for the XMPP candidate | | [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 6ae7ed5..6d26b99 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. @@ -22,7 +22,7 @@ - [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; done. -- [S00-018](../tasks/S00-018.md): Validate bounded standalone XML ingress for the XMPP candidate — protocol; review. +- [S00-018](../tasks/S00-018.md): Validate bounded standalone XML ingress for the XMPP candidate — protocol; done. - [S00-010](../tasks/S00-010.md): Gate: Профиль и проверка стека — qa; todo. ## Граница этапа diff --git a/planning/task_matrix.csv b/planning/task_matrix.csv index 417c356..fd95d0e 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-902594b44429,"S00-001, S00-002, S00-017, S00-018",Проверить XMPP WSS/auth библиотеку +S00-003,S00,protocol,qa,todo,,"S00-001, S00-002, S00-017, S00-018",Проверить 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 @@ -15,7 +15,7 @@ S00-014,S00,ci-cd,qa,done,auto-ci-cd-14343249da62,"S00-001, S00-011, S00-013",Fi 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,done,auto-protocol-599343cd9e3f,"S00-001, S00-002",Establish fail-closed SCRAM server-final validation -S00-018,S00,protocol,security,review,auto-protocol-89fe6563092c,"S00-001, S00-002, S00-017",Validate bounded standalone XML ingress for the XMPP candidate +S00-018,S00,protocol,security,done,auto-protocol-89fe6563092c,"S00-001, S00-002, S00-017",Validate bounded standalone XML ingress for the XMPP candidate 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-64dc2d9fa232.txt b/state/commit_messages/auto-security-64dc2d9fa232.txt new file mode 100644 index 0000000..20222c4 --- /dev/null +++ b/state/commit_messages/auto-security-64dc2d9fa232.txt @@ -0,0 +1,4 @@ +Approve bounded XML ingress after independent framing checks + +Changes: Accept the isolated S00-018 ingress experiment and bounded ADR; record independent security findings and review handoff. Preserve all browser, live WSS, interoperability and production resource limitations. +Validation: Fresh-cache npm ci and all 55 integrated tests passed on Node 24.21.0/npm 11.19.0; six additional adversarial documents rejected before real JXT.parse with stale callback/fresh attempt checks. Verified ten dependency licenses/integrities, 340 unchanged Stanza files, upstream saxes license bytes and matching digests. Stock defects reproduced; make check passed 72 tooling tests. Initial getter-only tracing attempt failed and is recorded separately. Scope/whitespace inspected; no browser or live WSS test. diff --git a/state/evidence/S00-018-review.md b/state/evidence/S00-018-review.md new file mode 100644 index 0000000..b2a73df --- /dev/null +++ b/state/evidence/S00-018-review.md @@ -0,0 +1,123 @@ +# S00-018 independent security review + +Reviewer: auto-security-64dc2d9fa232 (security). +Executor: auto-protocol-89fe6563092c (protocol). Date: 2026-10-15. +Decision: approve the bounded standalone XML ingress experiment and its ADR. + +Input: master/startup/role/workflow documents, assigned show/packet, required +TESTING/protocol role/ADR registry/blocker; exact ACC-004/NET-003/NET-004; +accepted scope, stack and SASL ADRs, direct dependency evidence/reviews/handoffs; +original parser blocker evidence/probe; executor source/tests/message/handoff. +Output: independent review evidence, accepted bounded ADR metadata and handoff. +No new shared contract or application implementation is introduced. + +## Findings against acceptance + +Implementation commit e2b4dbdb7628f5bf3c821fa89f69df8a6095926f and executor +commit message match the isolated transport integration, fixtures, exact pins, +notices and limitations. Scoped source and generated/state transition diff were +examined. Source paths stay within parser-validation and its ADR; other paths +are workflow metadata. Working tree was clean before review metadata. No specs, +shared interfaces, parent candidate, SASL implementation or plan definition edit. + +Finite UTF-16 precheck precedes TextEncoder, bounding its temporary allocation; +4096-byte precheck precedes SAX construction/write. A fresh namespace-aware XML +1.0 document parser validates every message and close() enforces completion. +Depth 8, elements 32, total attributes 16 including xmlns, aggregate attribute +units 1024, names 128 and decoded values 256 are inclusive local budgets before +JXT.parse/registry.import. SAX may retain one token/attribute before callbacks, +but the byte ceiling already bounds it. No DTD fetching/custom entities or +handwritten XML syntax parser. DTD/comment/PI/declaration reject. Malformed, +incomplete, multiple-root and binary input cannot emit an earlier complete root. +The aggregate-limit fixture and Unicode boundary import the exact actual body. + +Installed public Client.transports constructor declaration and Transport interface +agree with actual Client.connect selection. This bypasses the stock persistent +parser through a supported constructor registration, without a vendor patch or +post-import interception. Tests run actual Client/JXT/registry/queue; socket +injection captures external effects only and tracing invokes real methods. +Original large/deep/cross-message failure categories reject, with no stanza or +stream:start delivery. Disconnect marks terminal, detaches all four handlers, +clears socket/config/stream, and notifies Client reset. Failed restart and old +callbacks cannot revive the attempt; fresh Client.connect accepts valid input. +No raw XML/error text log/event, real credentials or conversations, crypto, +plaintext fallback, TLS/CORS bypass or invented channel binding found. + +Dependency graph has ten exact installed versions/licenses and HTTPS/SHA512 +lock entries. Preserved notices match shipped license texts; upstream saxes +v6.0.0 LICENSE independently retrieved over normal HTTPS matches byte-for-byte. +Strict TLS/engines and disabled lifecycle scripts retained. Stanza's 340 files +byte-match the parent candidate. Lock/license checks establish repeatability +and notices, not supply-chain provenance or vulnerability clearance. + +No acceptance defect or missing review input found. This is a local ingress +experiment, not a production transport/library selection. Browser message +allocation occurs before JS checks; aggregate traffic, queue growth, CPU rate +and downstream work remain unbounded. Full stream sequencing/error negotiation, +redirect/keepalive/language inheritance and exhaustive SAX/JXT equivalence are +not certified. Browser bundling/runtime, real WSS/server/client interoperability, +load/exhaustion and advisory/provenance audit were not executed. ACC/NET product +obligations and the remaining S00-003 experiment are not accepted by this review. + +## Actual independent commands and results + +All Node/npm commands used +PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH. +Previously reviewed isolated runtime reused; no new archive verification claimed. + +- python3 scripts/tasks.py resume --agent auto-security-64dc2d9fa232; show S00-018; + packet S00-018 --agent auto-security-64dc2d9fa232: exit 0 each. Review status, + distinct executor and done prerequisites confirmed; reviewer did not claim. +- Read-only git log --all --grep='^S00-018:' --oneline, git show e2b4dbd --stat, + scoped source and state/generated diffs; git status --short: exit 0. Initially + clean tree. Required artifact/source/test/dependency reads completed. +- npm ci --prefix experiments/0002-xmpp-library/parser-validation --ignore-scripts + --no-audit --no-fund --cache /private/tmp/luma-parser-review-64dc2d9fa232 + --fetch-retries=0 --fetch-timeout=15000: exit 0, new reviewer cache, ten packages. +- npm test --prefix experiments/0002-xmpp-library/parser-validation: exit 0, + 55 passed, zero failed/skipped/cancelled, 335.373333 ms. +- python3 experiments/0002-xmpp-library/parser-validation/check-dependencies.py: + exit 0, ten exact dependency/license/integrity checks and 340 unchanged files. + Lock SHA256 35b177d57aaf81778eaf3d3321b3f77eb1e755a46abee784ef62b8959aedd63c; + ingress e6399ff581f59d1f09b471234d6e4b8f2ed6b61804aa4eb0eef7dd3f8e3f2dbc; + saxes license 0fac2374380621b22e6b50451057721a9c52935b02d16d106a9f04897f061d0e. + All match executor evidence. +- node experiments/0002-xmpp-library/parser-probe/reproduce.mjs: exit 0, + stock accepted 18-write/65536-byte reassembly, 1048576-byte body and 256 nested + children. This reproduces defects, not safe behavior. +- Inline Node --input-type=module reviewer assertions: exit 0. Six additional + adversarial documents: complete stream-open plus unfinished second root, + 17 total namespace attributes, surrogate char reference, literal forbidden + CDATA close in text, 257 decoded character references in an attribute and + unfinished CDATA. Traced real Parser.parse (the JXT exported implementation) + invoked zero times on rejection and once per fresh boundary document. + All four captured callbacks replayed after reconnect; fresh transport remained + intact, no old delivery/error, exact boundary body imported. Tracing is process + memory only; no vendor file edit or fabricated parser result. +- npm --version: exit 0, 11.19.0; initial Node tracing error reported v24.21.0. +- Inline Python urllib HTTPS retrieval/assertion of the versioned saxes LICENSE: + exit 0; preserved bytes equal upstream. +- make check > /private/tmp/luma-S00-018-64dc2d9fa232-check.log 2>&1: exit 0; + 72 tooling tests in 17.775s. Foundation integrity only. +- git diff --check before review metadata: exit 0; final metadata whitespace + and scope checked before approval. + +Exploratory failed check: first inline Node tracing tried assigning jxt.parse; +exit 1, getter-only export TypeError before any assertions ran. Corrected tracing +wraps the writable underlying Parser module export and calls its real function; +subsequent assertions above passed. This initial attempt is not a passed check. +No required artifact or environment blocker resulted. + +Primary sources independently opened on 2026-10-15: +[RFC 7395 sections 3.2/3.3.3](https://www.rfc-editor.org/rfc/rfc7395.html#section-3.3.3) +for text/standalone framing, first character and one element per frame; +[versioned saxes README](https://raw.githubusercontent.com/lddubeau/saxes/v6.0.0/README.md) +for public parser/options/entity and token-limit behavior; and +[versioned license](https://raw.githubusercontent.com/lddubeau/saxes/v6.0.0/LICENSE). +The RFC supplies framing requirements, not numerical budgets. Shipped pinned +API/source supplies the exact extension and allocation-order evidence. + +Reviewer changes only ADR acceptance metadata/paragraph, report, handoff and +mandatory commit message, plus the CLI transition. Coordinator must commit +before any further session. This reviewer exits after approve and does not +continue S00-003 or launch another agent. diff --git a/state/handoffs/S00-018.md b/state/handoffs/S00-018.md index 9660efa..cdd0af5 100644 --- a/state/handoffs/S00-018.md +++ b/state/handoffs/S00-018.md @@ -37,3 +37,15 @@ accepted SASL experiment unchanged. No specs/shared interfaces/app modules or original candidate files changed. S00-003 remains separate; only reviewed done and coordinator commit allow a fresh original executor to continue it. This executor exits after submit; no commit/next agent/original work is performed. + + +Independent security review: auto-security-64dc2d9fa232, 2026-10-15. +Accepted bounded S00-018 and ADR after fresh-cache npm ci, all 55 integrated +tests, ten dependency/license/integrity checks, 340 unchanged vendor files, +upstream license byte comparison and make check (72 tests), all exit 0. +Additional six adversarial inputs rejected before real JXT.parse; all four +stale callbacks left fresh attempts unaffected and boundary bodies imported +exactly. Report: state/evidence/S00-018-review.md. No blocker or acceptance defect. +All browser/WSS/interoperability/aggregate resource/production limits above +remain. Coordinator owns the review commit. S00-003 can resume only as a fresh +assigned process after that commit; reviewer exits immediately after approve. diff --git a/state/tasks.json b/state/tasks.json index 227db9c..0483ca6 100644 --- a/state/tasks.json +++ b/state/tasks.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "revision": 45, + "revision": 46, "tasks": { "S00-001": { "status": "done", @@ -32,18 +32,16 @@ "completed_at": "2026-10-14T19:06:23+00:00" }, "S00-003": { - "status": "blocked", - "owner": "auto-protocol-902594b44429", + "status": "todo", + "owner": null, "started_at": "2026-10-14T19:20:57+00:00", - "reason": "S00-003 cannot attest parser limits: Stanza 12.22.1 exposes no resource bounds and its persistent WebSocket parser accepts large/deep XML and reassembles incomplete documents across separate input messages.", - "updated_at": "2026-10-14T19:24:00+00:00", - "blocked_by": [ - "S00-018" - ], + "reason": null, + "updated_at": "2026-10-14T19:35:55+00:00", + "blocked_by": [], "resume_status": "in_progress", "blocker_report": "state/blockers/S00-018.md", "handoff": "state/handoffs/S00-003.md", - "previous_owner": "auto-protocol-826aa6bc12ef", + "previous_owner": "auto-protocol-902594b44429", "resumed_after_blocker": true }, "S00-004": { @@ -1236,14 +1234,17 @@ "completed_at": "2026-10-14T19:20:57+00:00" }, "S00-018": { - "status": "review", + "status": "done", "owner": "auto-protocol-89fe6563092c", "external_wait": false, "reason": null, "started_at": "2026-10-14T19:24:01+00:00", - "updated_at": "2026-10-14T19:31:32+00:00", + "updated_at": "2026-10-14T19:35:55+00:00", "evidence": "state/evidence/S00-018-auto-protocol-89fe6563092c.md", - "handoff": "state/handoffs/S00-018.md" + "handoff": "state/handoffs/S00-018.md", + "reviewer": "auto-security-64dc2d9fa232", + "review_evidence": "state/evidence/S00-018-review.md", + "completed_at": "2026-10-14T19:35:55+00:00" } }, "events": [ @@ -1825,6 +1826,27 @@ "to": "review", "reason": null, "evidence": "state/evidence/S00-018-auto-protocol-89fe6563092c.md" + }, + { + "revision": 46, + "at": "2026-10-14T19:35:55+00:00", + "action": "auto-unblock", + "task": "S00-003", + "resolved_by": "S00-018", + "to": "todo", + "fresh_agent_required": true + }, + { + "revision": 46, + "at": "2026-10-14T19:35:55+00:00", + "action": "approve", + "task": "S00-018", + "agent": "auto-security-64dc2d9fa232", + "role": "security", + "from": "review", + "to": "done", + "reason": null, + "evidence": "state/evidence/S00-018-review.md" } ], "retired_agents": [