S00-003: Record blocked task and remediation handoff
Changes: Preserve incomplete work and blocker metadata for S00-003. This checkpoint does not mark implementation accepted. Validation: Session ended with status blocked. Blocker: 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. Task: S00-003 Agent: auto-protocol-902594b44429 Role: protocol Action: claim Status: blocked Task title: Проверить XMPP WSS/auth библиотеку
This commit is contained in:
1 parent
1850dbc39f
commit
f556fc0deb
14 files changed
+335
-24
No files matched your search
@@ -0,0 +1,57 @@
|
||||
// Bounded diagnostic of the stock parser; passing means the defect reproduced.
|
||||
// No network, credentials, vendor patch, or production implementation.
|
||||
import assert from 'node:assert/strict';
|
||||
import {createRequire} from 'node:module';
|
||||
const require = createRequire(import.meta.url);
|
||||
const Client = require('stanza/Client').default;
|
||||
const {StreamParser} = require('stanza/jxt');
|
||||
assert.equal(require('stanza/package.json').version, '12.22.1');
|
||||
const tick = () => new Promise(resolve => setImmediate(resolve));
|
||||
function harness() {
|
||||
const client = new Client({autoReconnect: false});
|
||||
// Same parser options as shipped transports/websocket.js.
|
||||
const parser = new StreamParser({registry: client.stanzas,
|
||||
wrappedStream: false, allowComments: false});
|
||||
const received = [], errors = [];
|
||||
parser.on('data', value => received.push(value));
|
||||
parser.on('error', error => errors.push(error));
|
||||
return {parser, received, errors};
|
||||
}
|
||||
const opening = '<message xmlns="jabber:client"><body>';
|
||||
const closing = '</body></message>';
|
||||
|
||||
const split = harness();
|
||||
split.parser.write(opening);
|
||||
for (let i = 0; i < 16; i++) split.parser.write('a'.repeat(4096));
|
||||
await tick();
|
||||
assert.equal(split.errors.length, 0);
|
||||
assert.equal(split.received.length, 0);
|
||||
assert.equal(split.parser.destroyed, false);
|
||||
split.parser.write(closing);
|
||||
await tick();
|
||||
assert.equal(split.errors.length, 0);
|
||||
assert.equal(split.received.length, 1);
|
||||
assert.equal(split.received[0].stanza.body.length, 65536);
|
||||
split.parser.destroy();
|
||||
console.log('stock: 18 separate writes reassembled into one 65536-byte body; no error');
|
||||
|
||||
const large = harness();
|
||||
large.parser.write(opening + 'b'.repeat(1048576) + closing);
|
||||
await tick();
|
||||
assert.equal(large.errors.length, 0);
|
||||
assert.equal(large.received.length, 1);
|
||||
assert.equal(large.received[0].stanza.body.length, 1048576);
|
||||
large.parser.destroy();
|
||||
console.log('stock: 1048576-byte body accepted; no error');
|
||||
|
||||
const deep = harness();
|
||||
deep.parser.write('<message xmlns="jabber:client">' + '<x>'.repeat(256) +
|
||||
'</x>'.repeat(256) + '</message>');
|
||||
await tick();
|
||||
assert.equal(deep.errors.length, 0);
|
||||
assert.equal(deep.received.length, 1);
|
||||
let element = deep.received[0].xml, depth = 0;
|
||||
while (element.children[0]) {element = element.children[0]; depth++;}
|
||||
assert.equal(depth, 256);
|
||||
deep.parser.destroy();
|
||||
console.log('stock: 256 nested child elements accepted; no error');
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
Зафиксировать Web scope, browser targets и проверенные кандидаты, не устанавливая непроверенный framework по догадке.
|
||||
|
||||
Задач: 17; entry: нет; exit: S00-010.
|
||||
Задач: 18; entry: нет; exit: S00-010.
|
||||
|
||||
## [S01: Предметные контракты](stages/S01.md)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Матрица задач
|
||||
|
||||
Generated; state revision **41**. Canonical status: state/tasks.json.
|
||||
Generated; state revision **43**. 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 | todo | | S00-001, S00-002, S00-017 | Проверить XMPP WSS/auth библиотеку |
|
||||
| [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-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,6 +20,7 @@ Generated; state revision **41**. 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 | todo | | 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 |
|
||||
|
||||
@@ -14,7 +14,7 @@ Allocated означает наличие плана/приёмки, а не р
|
||||
| ACC-001 | web | Web requirement; cross-platform clauses apply only in Web context. | S06-003, S21-001 |
|
||||
| ACC-002 | web | Web requirement; cross-platform clauses apply only in Web context. | S06-001, S21-001 |
|
||||
| ACC-003 | out_of_scope | Native host/port TCP configuration; Web uses ACC-004 WSS. | |
|
||||
| ACC-004 | web | Web requirement; cross-platform clauses apply only in Web context. | S00-003, S00-017, S05-001, S06-003, S21-001 |
|
||||
| ACC-004 | web | Web requirement; cross-platform clauses apply only in Web context. | S00-003, S00-017, S00-018, S05-001, S06-003, S21-001 |
|
||||
| ACC-005 | web | Web requirement; cross-platform clauses apply only in Web context. | S05-001, S06-011, S21-001 |
|
||||
| ACC-006 | web | Web requirement; cross-platform clauses apply only in Web context. | S06-003, S06-004, S21-001 |
|
||||
| ACC-007 | web | Web requirement; cross-platform clauses apply only in Web context. | S06-002, S06-009, S20-008, S21-001 |
|
||||
@@ -27,8 +27,8 @@ Allocated означает наличие плана/приёмки, а не р
|
||||
| ACC-014 | web | Web requirement; cross-platform clauses apply only in Web context. | S01-002, S02-010, S06-006, S06-010, S21-001 |
|
||||
| NET-001 | web | Web requirement; cross-platform clauses apply only in Web context. | S02-008, S05-001, S05-002, S05-009, S21-001 |
|
||||
| NET-002 | out_of_scope | Native transport discovery; Web WSS addressed by ACC-004/NET-001. | |
|
||||
| NET-003 | web | Web requirement; cross-platform clauses apply only in Web context. | S00-003, S00-017, S05-003, S21-001 |
|
||||
| NET-004 | web | Web requirement; cross-platform clauses apply only in Web context. | S00-003, S00-017, S05-003, S05-009, S21-001 |
|
||||
| NET-003 | web | Web requirement; cross-platform clauses apply only in Web context. | S00-003, S00-017, S00-018, S05-003, S21-001 |
|
||||
| NET-004 | web | Web requirement; cross-platform clauses apply only in Web context. | S00-003, S00-017, S00-018, S05-003, S05-009, S21-001 |
|
||||
| NET-005 | web | Web requirement; cross-platform clauses apply only in Web context. | S05-004, S21-001 |
|
||||
| NET-006 | web | Web requirement; cross-platform clauses apply only in Web context. | S05-002, S05-010, S06-004, S20-002, S21-001 |
|
||||
| NET-007 | web | Web requirement; cross-platform clauses apply only in Web context. | S05-007, S21-001 |
|
||||
|
||||
@@ -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; todo.
|
||||
- [S00-003](../tasks/S00-003.md): Проверить XMPP WSS/auth библиотеку — protocol; blocked.
|
||||
- [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,6 +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; todo.
|
||||
- [S00-010](../tasks/S00-010.md): Gate: Профиль и проверка стека — qa; todo.
|
||||
|
||||
## Граница этапа
|
||||
|
||||
@@ -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,todo,,"S00-001, S00-002, S00-017",Проверить XMPP WSS/auth библиотеку
|
||||
S00-003,S00,protocol,qa,blocked,auto-protocol-902594b44429,"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,6 +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,todo,,"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
|
||||
|
||||
|
+61
-1
@@ -268,7 +268,8 @@
|
||||
"depends_on": [
|
||||
"S00-001",
|
||||
"S00-002",
|
||||
"S00-017"
|
||||
"S00-017",
|
||||
"S00-018"
|
||||
],
|
||||
"requirements": [
|
||||
"ACC-004",
|
||||
@@ -995,6 +996,65 @@
|
||||
],
|
||||
"context_budget_chars": 48000
|
||||
},
|
||||
{
|
||||
"id": "S00-018",
|
||||
"stage": "S00",
|
||||
"kind": "blocker",
|
||||
"root_task": "S00-003",
|
||||
"blocker_depth": 1,
|
||||
"unblocks": [
|
||||
"S00-003"
|
||||
],
|
||||
"role": "protocol",
|
||||
"reviewer_role": "security",
|
||||
"title": "Validate bounded standalone XML ingress for the XMPP candidate",
|
||||
"outcome": "One isolated runnable and independently reviewed ingress experiment enforces explicit finite XML resource limits and standalone text XML per WebSocket message before unsafe accumulation/import, through a supported library integration path.",
|
||||
"depends_on": [
|
||||
"S00-001",
|
||||
"S00-002",
|
||||
"S00-017"
|
||||
],
|
||||
"requirements": [
|
||||
"ACC-004",
|
||||
"NET-003",
|
||||
"NET-004"
|
||||
],
|
||||
"scope": [
|
||||
"experiments/0002-xmpp-library/parser-validation/**",
|
||||
"docs/decisions/0002-xmpp-parser-validation.md"
|
||||
],
|
||||
"inputs": [
|
||||
"docs/WEB_PROFILE.md",
|
||||
"docs/ARCHITECTURE.md",
|
||||
"docs/CONTRACTS.md",
|
||||
"docs/TESTING.md",
|
||||
"roles/protocol.md",
|
||||
"docs/decisions/README.md",
|
||||
"state/blockers/S00-018.md"
|
||||
],
|
||||
"spec_sections": [],
|
||||
"ui_sections": [],
|
||||
"steps": [
|
||||
"Read original blocker evidence, bounded probe, shipped parser/transport APIs and RFC 7395 framing; reproduce the stock failure with finite synthetic input.",
|
||||
"Choose and document a supported ingress integration using vetted existing XML parsing; keep limits experiment-local, do not implement a handwritten security XML parser or patch ignored vendor sources.",
|
||||
"Enforce byte/depth/element/attribute budgets and complete single-document text-message framing before unbounded tree/import work; reject invalid input terminally and clear attempt state.",
|
||||
"Add valid boundary and adversarial fixtures including incomplete messages, multiple roots, oversized tokens/attributes, deep XML, malformed XML and binary messages; verify rejection causes no stanza delivery or retained cross-message state.",
|
||||
"Record exact dependencies/licenses/browser API constraints if adding packages, runnable commands/results and limitations, then submit for independent security review."
|
||||
],
|
||||
"acceptance": [
|
||||
"Explicit finite byte/depth/element/attribute budgets are enforced before uncontrolled accumulation/import; boundary-valid stanza still parses with actual library behavior.",
|
||||
"Each WebSocket message is one complete standalone text XML document; incomplete/multiple-root/binary input is rejected and cannot be revived by a later message.",
|
||||
"Original large/deep/cross-message failure categories are rejected under documented local limits without post-import-only checks, vendor patch or TLS/CORS bypass.",
|
||||
"One supported integration path and cleanup/reset behavior are demonstrated by runnable actual ingress tests; no production shared contract, auth policy or product limit change."
|
||||
],
|
||||
"checks": [
|
||||
"Positive boundary-valid framed stanza using the actual candidate registry/parser and ingress integration.",
|
||||
"Original bounded probe categories exceed local budgets or fail framing and produce terminal rejection without stanza emission.",
|
||||
"Malformed/unfinished/multiple-root/binary/oversized-token/attribute/depth/element cases; no cross-message retained state or late revival.",
|
||||
"Fresh attempt/reset accepts valid input; dependency pin/license/API and scope inspection."
|
||||
],
|
||||
"context_budget_chars": 48000
|
||||
},
|
||||
{
|
||||
"id": "S00-010",
|
||||
"stage": "S00",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
- Этап: S00
|
||||
- Оператор: protocol
|
||||
- Reviewer: qa
|
||||
- Зависимости: S00-001, S00-002, S00-017
|
||||
- Зависимости: S00-001, S00-002, S00-017, S00-018
|
||||
- Требования: ACC-004, NET-003, NET-004
|
||||
|
||||
## Один результат
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
# S00-018: Validate bounded standalone XML ingress for the XMPP candidate
|
||||
|
||||
- Remediation для: S00-003; root: S00-003; depth: 1
|
||||
|
||||
> Generated from planning/tasks.json; status is in state/tasks.json.
|
||||
|
||||
- Этап: S00
|
||||
- Оператор: protocol
|
||||
- Reviewer: security
|
||||
- Зависимости: S00-001, S00-002, S00-017
|
||||
- Требования: ACC-004, NET-003, NET-004
|
||||
|
||||
## Один результат
|
||||
|
||||
One isolated runnable and independently reviewed ingress experiment enforces explicit finite XML resource limits and standalone text XML per WebSocket message before unsafe accumulation/import, through a supported library integration path.
|
||||
|
||||
## Разрешённые пути
|
||||
|
||||
- `experiments/0002-xmpp-library/parser-validation/**`
|
||||
- `docs/decisions/0002-xmpp-parser-validation.md`
|
||||
|
||||
Не изменять другие modules, shared contracts или spec snapshots без изменения плана. Stem без расширения разрешает принятые stack-specific extensions и focused test рядом.
|
||||
|
||||
## Прочитать
|
||||
|
||||
- docs/WEB_PROFILE.md
|
||||
- docs/ARCHITECTURE.md
|
||||
- docs/CONTRACTS.md
|
||||
- docs/TESTING.md
|
||||
- roles/protocol.md
|
||||
- docs/decisions/README.md
|
||||
- state/blockers/S00-018.md
|
||||
|
||||
## Шаги
|
||||
|
||||
1. Read original blocker evidence, bounded probe, shipped parser/transport APIs and RFC 7395 framing; reproduce the stock failure with finite synthetic input.
|
||||
2. Choose and document a supported ingress integration using vetted existing XML parsing; keep limits experiment-local, do not implement a handwritten security XML parser or patch ignored vendor sources.
|
||||
3. Enforce byte/depth/element/attribute budgets and complete single-document text-message framing before unbounded tree/import work; reject invalid input terminally and clear attempt state.
|
||||
4. Add valid boundary and adversarial fixtures including incomplete messages, multiple roots, oversized tokens/attributes, deep XML, malformed XML and binary messages; verify rejection causes no stanza delivery or retained cross-message state.
|
||||
5. Record exact dependencies/licenses/browser API constraints if adding packages, runnable commands/results and limitations, then submit for independent security review.
|
||||
|
||||
## Приёмка
|
||||
|
||||
1. Explicit finite byte/depth/element/attribute budgets are enforced before uncontrolled accumulation/import; boundary-valid stanza still parses with actual library behavior.
|
||||
2. Each WebSocket message is one complete standalone text XML document; incomplete/multiple-root/binary input is rejected and cannot be revived by a later message.
|
||||
3. Original large/deep/cross-message failure categories are rejected under documented local limits without post-import-only checks, vendor patch or TLS/CORS bypass.
|
||||
4. One supported integration path and cleanup/reset behavior are demonstrated by runnable actual ingress tests; no production shared contract, auth policy or product limit change.
|
||||
|
||||
## Focused checks
|
||||
|
||||
1. Positive boundary-valid framed stanza using the actual candidate registry/parser and ingress integration.
|
||||
2. Original bounded probe categories exceed local budgets or fail framing and produce terminal rejection without stanza emission.
|
||||
3. Malformed/unfinished/multiple-root/binary/oversized-token/attribute/depth/element cases; no cross-message retained state or late revival.
|
||||
4. Fresh attempt/reset accepts valid input; dependency pin/license/API and scope inspection.
|
||||
|
||||
## Блокер и завершение запуска
|
||||
|
||||
Для всех ролей scope — только эта задача. При блокере создать issue JSON по state/ISSUE_TEMPLATE.json, вызвать escalate с текущим ID/role/agent, проверить status=blocked и resolution_task, затем немедленно завершить запуск. Не решать blocker и не выбирать следующую задачу самому. Новый агент назначается runner. Правки metadata через CLI — единственное исключение scope.
|
||||
|
||||
## Передача
|
||||
|
||||
Сохранить evidence/handoff; submit → review и завершить запуск. Reviewer также выполняет только эту задачу, включая обязательное escalate при блокере.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Blocker S00-018
|
||||
|
||||
- Original task: S00-003
|
||||
- Root task: S00-003
|
||||
- Reporter: auto-protocol-902594b44429
|
||||
- Role: protocol
|
||||
- Original owner: auto-protocol-902594b44429
|
||||
- Waits for user/external condition: False
|
||||
|
||||
## Cause
|
||||
|
||||
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.
|
||||
|
||||
## One remediation outcome
|
||||
|
||||
One isolated runnable and independently reviewed ingress experiment enforces explicit finite XML resource limits and standalone text XML per WebSocket message before unsafe accumulation/import, through a supported library integration path.
|
||||
|
||||
## Evidence / reproduction
|
||||
|
||||
Run the pinned Node command in state/evidence/S00-003-auto-protocol-902594b44429.md: parser-probe/reproduce.mjs exits 0 after observing acceptance of a 1 MiB body, depth 256, and unfinished XML retained across 18 writes. Inspect stanza/transports/websocket.js and jxt/StreamParser.d.ts for absent per-message completeness/resource-limit enforcement.
|
||||
|
||||
The reporting agent must stop now. A new agent implements only S00-018.
|
||||
@@ -0,0 +1,39 @@
|
||||
# S00-003 parser-limit blocker evidence
|
||||
|
||||
Executor: auto-protocol-902594b44429, protocol. Date: 2026-10-15.
|
||||
Result: bounded diagnostic reproduced missing input limits; library selection remains incomplete.
|
||||
|
||||
Input: assigned master/startup/role/workflow documents, resume/show/packet, card and previous handoff; required docs/TESTING.md and docs/decisions/README.md; exact ACC-004/NET-003/NET-004; accepted ADR 0000, 0001-stack and 0002-xmpp-sasl-validation; all direct dependency executor/review evidence and handoffs. S00-017 is done and its prior SASL blocker is resolved within its reviewed fixture scope. S01 shared contracts are still future work; no shared interface is introduced.
|
||||
|
||||
Intended output: one library-selection ADR and runnable WSS/auth/parser/extension spike. Focused acceptance includes actual WSS handshake, verified SCRAM, bounded parser input and no invented TLS binding. This run stops before selection because parser bounds cannot be attested for the candidate's stock input path.
|
||||
|
||||
## Actual diagnostic
|
||||
|
||||
Added only experiments/0002-xmpp-library/parser-probe/reproduce.mjs, using the existing installed Stanza 12.22.1 and actual Client registry/StreamParser. No dependency, lockfile, accepted SASL plugin, vendor source, spec or app module changed. The script uses exactly the shipped WebSocket parser options: wrappedStream=false and allowComments=false. It asserts version, received stanza/body/XML depth and absence of error. No parser or registry result is stubbed. Finite fixtures have no accounts or real conversations; no network connection or authentication occurs.
|
||||
|
||||
Command:
|
||||
`PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH node experiments/0002-xmpp-library/parser-probe/reproduce.mjs`
|
||||
Exit 0, actual stdout:
|
||||
|
||||
```text
|
||||
stock: 18 separate writes reassembled into one 65536-byte body; no error
|
||||
stock: 1048576-byte body accepted; no error
|
||||
stock: 256 nested child elements accepted; no error
|
||||
```
|
||||
|
||||
Passing assertions mean stock limitations were reproduced, not safe parsing. The first case writes an unfinished message/body, sixteen 4096-byte chunks, then closing tags. Before closure there is no error/output and parser remains alive; after closure the entire body is emitted. The second and third cases show large and deep complete input accepted. This is not a memory-exhaustion benchmark or proof of infinite capacity; no crash/unbounded allocation was attempted and no product limit value is invented.
|
||||
|
||||
Version-pinned source inspection: stanza/jxt/StreamParser.d.ts exposes no byte/depth/element/attribute limit options. StreamParser.js builds nested element trees/text; Parser.js appends characters to recordBuffer across writes. stanza/transports/websocket.js creates one persistent parser, converts each socket.onmessage payload to text and writes it without checking completeness, size/depth, or text-message type. Therefore these separate parser writes model the transport's per-message ingress; actual WebSocket/TLS execution is NOT claimed. Browser WebSocket APIs also do not make a remote XML payload safe merely by using TLS.
|
||||
|
||||
Primary sources opened with web tool on 2026-10-15: RFC 7395 and upstream Stanza/xmpp.js repositories. [RFC 7395 section 3.3.3](https://www.rfc-editor.org/rfc/rfc7395.html#section-3.3.3) requires standalone XML per WebSocket message. The observed reassembly conflicts with that framing requirement when each write represents a distinct WebSocket message (inference from shipped transport source). Resource-limit absence is established by shipped API/source plus the finite examples, not by an RFC maximum. The alternative xmpp.js is not installed or tested and not selected as a safe replacement.
|
||||
|
||||
## Commands and limitations
|
||||
|
||||
- python3 scripts/tasks.py resume --agent auto-protocol-902594b44429; show S00-003; packet S00-003 --agent auto-protocol-902594b44429: exit 0 each; existing assigned task, no repeated claim.
|
||||
- Initial git status --short: exit 0, only coordinator claim modification in state/tasks.json.
|
||||
- Diagnostic command above: exit 0, all three cases reproduced in 0.154 seconds tool wall time.
|
||||
- Exploratory guessed 0001-web-stack.md, lib/StreamParser.js and experiments/0017-scram-server-final paths were absent; actual required ADR/parser/remediation paths were located and read. These failed exploratory reads are not passed checks or missing required inputs.
|
||||
|
||||
Source edits stopped immediately after reproduction. No make check, clean npm ci, fresh SASL test run, browser build/runtime, real WSS handshake, complete NET-003 selection, extension roundtrip or independent interoperability was performed in this session. Parent npm test still points to absent future tests; do not use it as completed spike. No selection ADR was written. Existing dependency acceptance is reported as prior evidence, not re-executed validation. No certificate/CORS workaround, invented binding, crypto primitive, real credentials or Git mutation.
|
||||
|
||||
Next: separately reviewed atomic bounded frame/parser ingress experiment; original library selection resumes only in a fresh assigned session after resolver done and coordinator commit.
|
||||
@@ -1,11 +1,14 @@
|
||||
# S00-003 blocked handoff
|
||||
|
||||
Executor: auto-protocol-826aa6bc12ef, protocol. Original scope: library selection and WSS/auth/parser/extension spike.
|
||||
Executor: auto-protocol-902594b44429, protocol, 2026-10-15.
|
||||
Original outcome remains library selection with WSS/auth/parser/extension spike.
|
||||
|
||||
Reached: inspected StanzaJS 12.22.1 and xmpp.js primary sources; created an exploratory pinned Stanza manifest/lock under experiments/0002-xmpp-library. Stanza's actual registered SASL handler was reproduced accepting empty and forged server-final before challenge/proof and requesting restart. See state/evidence/S00-003-auto-protocol-826aa6bc12ef.md for exact runnable reproduction/commands and limitations.
|
||||
Prior S00-017 SASL validation remediation is independently accepted. Read its ADR/plugin/44-test evidence; this session did not rerun those tests or change that experiment. Stanza is still an unselected candidate and the parent exploratory manifest/lock remain incomplete.
|
||||
|
||||
Blocker: cannot attest safe SCRAM authentication with the candidate's unverified server-final success path. Its SCRAM implementation exposes finalize verification but its feature handler never calls it. Alternative xmpp.js upstream source likewise completes on success without verifier processing; this alternative was not installed/tested. A separately reviewed fail-closed SASL validation experiment is required; no handwritten cryptographic primitives or upstream source patch should be improvised in original selection.
|
||||
New bounded probe: experiments/0002-xmpp-library/parser-probe/reproduce.mjs. With the accepted Node 24.21.0 runtime, its actual parser/Client registry accepts a 1 MiB body and 256 nested children and retains/reassembles unfinished XML across 18 writes into a 64 KiB body without error. StreamParserOptions exposes no resource-limit configuration. The shipped WebSocket transport forwards successive messages to that persistent parser without enforcing standalone XML or limits. Evidence and exact command: state/evidence/S00-003-auto-protocol-902594b44429.md. This is a local diagnostic, not WSS/server/browser execution or an exhaustion benchmark.
|
||||
|
||||
Source edits stopped. Manifest/lock are an unaccepted exploratory checkpoint, not a complete spike; npm test points at future tests. No ADR 0002 selection written. WSS, parser bounds, extension roundtrip, browser support and valid SCRAM are unverified. No make check result or release readiness claimed. Secrets/account fixtures are invented; no network auth was sent.
|
||||
Blocker: cannot attest the required bounded parser ingress using the candidate's stock input path. Needs one separately reviewed experiment enforcing finite input resource limits and complete standalone text XML per WebSocket message, using vetted parsing and a supported integration path. Do not patch ignored vendor source or rely on post-import events after allocations. Keep policy local to the experiment; no shared contract/product-limit decision is authorized here.
|
||||
|
||||
Next input: new resolver agent implements only the atomic server-final validation outcome in the issue, with actual negative and valid-vector evidence; independent security reviewer validates it. After reviewed done, a fresh original executor resumes library selection and completes all original focused checks. Reporter must exit after escalate; coordinator owns commits/process launches.
|
||||
Source edits stopped after diagnosis. No selection ADR, actual WSS handshake, browser build/runtime, complete mechanism policy, module extension roundtrip or independent interoperability is completed. No make check/clean install claimed for this run; source/accepted dependencies/specs were not altered beyond the bounded probe.
|
||||
|
||||
Next input: fresh resolver agent performs only the issue's parser ingress experiment and independent reviewer validates it. Only after reviewed done and coordinator commit may a new original executor resume remaining S00-003 acceptance. Current reporter must exit after escalation, cannot implement resolver, unblock, claim again or launch another agent.
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"title": "Validate bounded standalone XML ingress for the XMPP candidate",
|
||||
"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.",
|
||||
"reproduction": "Run the pinned Node command in state/evidence/S00-003-auto-protocol-902594b44429.md: parser-probe/reproduce.mjs exits 0 after observing acceptance of a 1 MiB body, depth 256, and unfinished XML retained across 18 writes. Inspect stanza/transports/websocket.js and jxt/StreamParser.d.ts for absent per-message completeness/resource-limit enforcement.",
|
||||
"role": "protocol",
|
||||
"reviewer_role": "security",
|
||||
"scope": [
|
||||
"experiments/0002-xmpp-library/parser-validation/**",
|
||||
"docs/decisions/0002-xmpp-parser-validation.md"
|
||||
],
|
||||
"outcome": "One isolated runnable and independently reviewed ingress experiment enforces explicit finite XML resource limits and standalone text XML per WebSocket message before unsafe accumulation/import, through a supported library integration path.",
|
||||
"steps": [
|
||||
"Read original blocker evidence, bounded probe, shipped parser/transport APIs and RFC 7395 framing; reproduce the stock failure with finite synthetic input.",
|
||||
"Choose and document a supported ingress integration using vetted existing XML parsing; keep limits experiment-local, do not implement a handwritten security XML parser or patch ignored vendor sources.",
|
||||
"Enforce byte/depth/element/attribute budgets and complete single-document text-message framing before unbounded tree/import work; reject invalid input terminally and clear attempt state.",
|
||||
"Add valid boundary and adversarial fixtures including incomplete messages, multiple roots, oversized tokens/attributes, deep XML, malformed XML and binary messages; verify rejection causes no stanza delivery or retained cross-message state.",
|
||||
"Record exact dependencies/licenses/browser API constraints if adding packages, runnable commands/results and limitations, then submit for independent security review."
|
||||
],
|
||||
"acceptance": [
|
||||
"Explicit finite byte/depth/element/attribute budgets are enforced before uncontrolled accumulation/import; boundary-valid stanza still parses with actual library behavior.",
|
||||
"Each WebSocket message is one complete standalone text XML document; incomplete/multiple-root/binary input is rejected and cannot be revived by a later message.",
|
||||
"Original large/deep/cross-message failure categories are rejected under documented local limits without post-import-only checks, vendor patch or TLS/CORS bypass.",
|
||||
"One supported integration path and cleanup/reset behavior are demonstrated by runnable actual ingress tests; no production shared contract, auth policy or product limit change."
|
||||
],
|
||||
"checks": [
|
||||
"Positive boundary-valid framed stanza using the actual candidate registry/parser and ingress integration.",
|
||||
"Original bounded probe categories exceed local budgets or fail framing and produce terminal rejection without stanza emission.",
|
||||
"Malformed/unfinished/multiple-root/binary/oversized-token/attribute/depth/element cases; no cross-message retained state or late revival.",
|
||||
"Fresh attempt/reset accepts valid input; dependency pin/license/API and scope inspection."
|
||||
],
|
||||
"depends_on": [],
|
||||
"requires_user_input": false
|
||||
}
|
||||
+41
-9
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"revision": 41,
|
||||
"revision": 43,
|
||||
"tasks": {
|
||||
"S00-001": {
|
||||
"status": "done",
|
||||
@@ -32,14 +32,16 @@
|
||||
"completed_at": "2026-10-14T19:06:23+00:00"
|
||||
},
|
||||
"S00-003": {
|
||||
"status": "todo",
|
||||
"owner": null,
|
||||
"started_at": "2026-10-14T19:06:24+00:00",
|
||||
"reason": null,
|
||||
"updated_at": "2026-10-14T19:20:57+00:00",
|
||||
"blocked_by": [],
|
||||
"status": "blocked",
|
||||
"owner": "auto-protocol-902594b44429",
|
||||
"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"
|
||||
],
|
||||
"resume_status": "in_progress",
|
||||
"blocker_report": "state/blockers/S00-017.md",
|
||||
"blocker_report": "state/blockers/S00-018.md",
|
||||
"handoff": "state/handoffs/S00-003.md",
|
||||
"previous_owner": "auto-protocol-826aa6bc12ef",
|
||||
"resumed_after_blocker": true
|
||||
@@ -1232,6 +1234,12 @@
|
||||
"reviewer": "auto-security-9ab954f6e021",
|
||||
"review_evidence": "state/evidence/S00-017-review.md",
|
||||
"completed_at": "2026-10-14T19:20:57+00:00"
|
||||
},
|
||||
"S00-018": {
|
||||
"status": "todo",
|
||||
"owner": null,
|
||||
"external_wait": false,
|
||||
"reason": null
|
||||
}
|
||||
},
|
||||
"events": [
|
||||
@@ -1767,6 +1775,29 @@
|
||||
"to": "done",
|
||||
"reason": null,
|
||||
"evidence": "state/evidence/S00-017-review.md"
|
||||
},
|
||||
{
|
||||
"revision": 42,
|
||||
"at": "2026-10-14T19:20:57+00:00",
|
||||
"action": "claim",
|
||||
"task": "S00-003",
|
||||
"agent": "auto-protocol-902594b44429",
|
||||
"role": "protocol",
|
||||
"from": "todo",
|
||||
"to": "in_progress",
|
||||
"reason": null
|
||||
},
|
||||
{
|
||||
"revision": 43,
|
||||
"at": "2026-10-14T19:24:00+00:00",
|
||||
"action": "escalate",
|
||||
"task": "S00-003",
|
||||
"resolution_task": "S00-018",
|
||||
"agent": "auto-protocol-902594b44429",
|
||||
"role": "protocol",
|
||||
"from": "in_progress",
|
||||
"to": "blocked",
|
||||
"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."
|
||||
}
|
||||
],
|
||||
"retired_agents": [
|
||||
@@ -1776,6 +1807,7 @@
|
||||
"auto-ci-cd-28868645424b",
|
||||
"auto-qa-98b05bd56c25",
|
||||
"auto-ci-cd-5475930af078",
|
||||
"auto-protocol-826aa6bc12ef"
|
||||
"auto-protocol-826aa6bc12ef",
|
||||
"auto-protocol-902594b44429"
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user