From 810dc8ea75b764a7f3115e2976e181c41fcc2d8b Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Tue, 25 Aug 2026 14:40:52 +0200 Subject: [PATCH] fix(ticket-083): bound large comparison graphs --- TODO.md | 5 +++-- project/ticket-083/README.md | 23 ++++++++++++++++--- project/ticket-083/ai-codex-logs.txt | 33 ++++++++++++++++++++++++++++ project/ticket-083/ai-codex.md | 10 +++++++-- project/ticket-083/changelog.md | 8 +++++++ project/ticket-083/intent.json | 14 +++++++----- src/comparison/workspace.ts | 11 ++++++++-- test/workspace.test.ts | 7 ++++++ 8 files changed, 96 insertions(+), 15 deletions(-) diff --git a/TODO.md b/TODO.md index f137b4a..558f011 100644 --- a/TODO.md +++ b/TODO.md @@ -6,8 +6,9 @@ acceptance criteria to their governed source ticket. Current state: `IN_PROGRESS / PUBLICATION`. - [ ] [`ticket-083`](project/ticket-083/README.md) — keep workspace comparison - artifacts and caches outside analysed repository state. Current state: - `IN_PROGRESS / PUBLICATION`. + artifacts bounded and outside analysed repository state; live `PLF-8091` + showed a generated Platform graph above the generic JSON ceiling. Current + state: `IN_PROGRESS / PUBLICATION`. - [ ] [`ticket-084`](project/ticket-084/README.md) — honor explicit deterministic NL mode in compare-workspace CLI. Current state: `IN_PROGRESS / PUBLICATION`. diff --git a/project/ticket-083/README.md b/project/ticket-083/README.md index 7c167e3..1c7a169 100644 --- a/project/ticket-083/README.md +++ b/project/ticket-083/README.md @@ -1,7 +1,7 @@ -# Ticket 083: Keep workspace comparison evidence outside analysed state +# Ticket 083: Keep workspace comparison bounded and outside analysed state - **ID**: ticket-083 -- **Owner**: unresolved:human +- **Owner**: agent:codex - **Status**: IN_PROGRESS - **Workflow state**: PUBLICATION - **Created**: 2026-08-21 @@ -12,7 +12,9 @@ Make `compare-workspace` observationally pure with respect to the repository it analyses. Its requested output directory must control both pipeline artifacts and extractor caches, including when that directory is outside the repository. Generated evidence must not appear in the captured Git status or in either -intent graph. +intent graph. A generated graph that exceeds the generic JSON-document ceiling +but remains within the comparison-specific resource budget must be readable by +the comparator without weakening limits for unrelated JSON consumers. ## Acceptance criteria @@ -23,6 +25,9 @@ intent graph. - [x] AC-03: Comparison status is captured before output creation and excludes the selected in-repository output directory when it already exists. - [x] AC-04: Focused, full Node, governance and Docker checks pass. +- [x] AC-05: `compare-workspace` accepts the observed 142,557,246-byte Platform + graph under an explicit 256 MiB ceiling while still rejecting graphs + above that bounded comparison limit. ## Participants @@ -36,11 +41,18 @@ followed by explicit continuation, authorizes this bounded defect repair. This conversation note is not merge authorization; protected exact-head Validator evidence remains required. +On 2026-08-25 the Subactor coding-agent independently reproduced the live +failure on `PLF-8091`; the Founder asked the supervisor to continue and repair +autonomization defects found through observation. Exact stderr proved that both +pipelines completed but the comparator rejected a 142,557,246-byte generated +graph at the generic 128 MiB read ceiling. + ## Non-goals - No change to comparison scoring or authority semantics. - No automatic application, approval, merge or ticket closure. - No new dependency or public schema. +- No unbounded graph reads and no increase to the generic JSON read ceiling. ## Verification evidence @@ -51,3 +63,8 @@ evidence remains required. schema gates pass. - `make docker-smoke`, governance and diff checks pass locally. Protected exact-head review remains pending. +- The 2026-08-25 exact Platform replay passed `compare-workspace` with a + 142,557,246-byte generated graph and zero stderr. It then surfaced the real + semantic delta (`blocking +2`) instead of a file-size stack trace. +- Current verification passes 426 tests (425 pass, one JDK-only skip), focused + workspace 4/4, governance with zero findings and Docker smoke. diff --git a/project/ticket-083/ai-codex-logs.txt b/project/ticket-083/ai-codex-logs.txt index 2d49ff3..c4ce593 100644 --- a/project/ticket-083/ai-codex-logs.txt +++ b/project/ticket-083/ai-codex-logs.txt @@ -6,3 +6,36 @@ PASS: 421 tests, 1 JDK-only skip $ make docker-smoke docker smoke: PASS + +2026-08-25 live Subactor reproduction + +Source ticket: PLF-8091; target repository: subactor/platform; base: +92a79e060f18cd5793cdb50138e2f7b1241b8c1d. + +The coding-agent runner passed its repository and governance checks, then +failed in the pinned todo2code comparison. Replaying the exact retained patch +and command against todo2code ea6ce38 produced: + + File exceeds 134217728 bytes: .../.intent-compare-base/.../intent.graph.json + +The current-workspace graph was 142,557,246 bytes. Both pipelines had completed; +the generic read ceiling, not an intent regression, rejected their generated +evidence. User authorization to continue includes repairing autonomization +defects observed by the supervisor. Merge authority remains protected. + +$ npm run build && node --test dist/test/workspace.test.js +PASS: 4/4 tests, including the bounded large-graph ceiling regression. + +$ ./project/governance-check.sh --actor agent --base ea6ce38... --head HEAD +GOV-PASS: 0 errors, 0 warnings. + +$ npm run verify +PASS: 426 tests; 425 pass, 0 fail, 1 JDK-only skip. + +$ make docker-smoke +PASS: image build and runtime smoke. + +$ compare-workspace --base origin/main +PASS: exit 0, stderr 0 bytes; current graph 142,557,246 bytes; base commit +92a79e060f18cd5793cdb50138e2f7b1241b8c1d. The comparison now reports the +actual semantic delta (blocking +2) for independent replanning. diff --git a/project/ticket-083/ai-codex.md b/project/ticket-083/ai-codex.md index 5e242b1..4dc3161 100644 --- a/project/ticket-083/ai-codex.md +++ b/project/ticket-083/ai-codex.md @@ -30,7 +30,13 @@ input. The comparison then observes artifacts produced by the observer. excluded the selected in-repository evidence path from the status snapshot. - Added regression coverage and passed focused, full Node and Docker checks. - Transitioned to `IN_PROGRESS / PUBLICATION`; no merge is claimed locally. +- Reopened the merged comparison workstream after live `PLF-8091` evidence + showed a 142,557,246-byte generated Platform graph failing the generic + 128 MiB JSON ceiling. +- Kept the generic JSON limit unchanged and introduced a comparison-only, + bounded 256 MiB graph ceiling with focused regression coverage. -## Blockers +## Current state -- None for implementation; protected publication remains independent. +- `IN_PROGRESS / PUBLICATION`; the exact 142,557,246-byte Platform graph replay, + 426-test suite, governance and Docker gates pass. Protected review remains. diff --git a/project/ticket-083/changelog.md b/project/ticket-083/changelog.md index fdb7308..bfba2fe 100644 --- a/project/ticket-083/changelog.md +++ b/project/ticket-083/changelog.md @@ -7,3 +7,11 @@ - Bound the accepted plan for observationally pure workspace evidence. - Kept extractor caches under the selected comparison output and excluded generated evidence from observed Git state. + +## [0.2.0] - 2026-08-25 + +- Reopened the comparison workstream from live Subactor ticket `PLF-8091`. +- Added a comparison-specific 256 MiB ceiling for generated intent graphs; + retained the generic 128 MiB JSON ceiling for all other consumers. +- Added regression evidence bound to the observed 142,557,246-byte Platform + graph that previously failed after both pipelines completed. diff --git a/project/ticket-083/intent.json b/project/ticket-083/intent.json index 93002b5..09dae70 100644 --- a/project/ticket-083/intent.json +++ b/project/ticket-083/intent.json @@ -1,7 +1,7 @@ { "schema": "new-project.intent/v3", "ticket": "ticket-083", - "summary": "Keep workspace comparison artifacts and caches outside the analysed repository state", + "summary": "Keep workspace comparison artifacts bounded and outside the analysed repository state", "workstream": "core-dsl", "classification": { "kind": "BUG", @@ -29,13 +29,14 @@ "conflictsWith": [], "integrationTicket": null, "delivery": { - "acceptedBaseSha": "d14bb260581e9c3f0fbe04f9f475a185476dd358", + "acceptedBaseSha": "ea6ce38f4b4038a5d9937e83e04704b2d0906bc7", "targetBranch": "main", - "outcome": "compare-workspace writes every generated artifact and cache only below its selected output directory without affecting observed repository state", + "outcome": "compare-workspace writes generated artifacts only below its selected output directory and reads large generated graphs under a comparison-specific bounded ceiling", "nonGoals": [ "No scoring or DSL schema change", "No mutation authority", - "No CLI parsing change" + "No CLI parsing change", + "No unbounded reads or generic JSON ceiling increase" ], "complexity": "XS", "estimatedMinutes": 20, @@ -47,7 +48,7 @@ }, "architecture": { "status": "accepted", - "decision": "Derive a comparison-local config whose outputDir follows each pipeline root and selected evidence directory, and filter only the selected generated path from the pre-run status snapshot", + "decision": "Keep comparison output isolated and apply an explicit 256 MiB ceiling only when re-reading the two generated comparison graphs", "components": [ {"name": "workspace-comparison", "paths": ["src/comparison/workspace.ts", "test/workspace.test.ts"]} ], @@ -61,7 +62,8 @@ "validation": [ {"criterion": "AC-02", "commands": ["node --test dist/test/workspace.test.js"], "evidence": "External output regression leaves no generated directory in the analysed repository"}, {"criterion": "AC-03", "commands": ["node --test dist/test/workspace.test.js"], "evidence": "Selected in-tree evidence is absent from changedFiles and graph input"}, - {"criterion": "AC-04", "commands": ["npm run verify", "./project/governance-check.sh", "make docker-smoke"], "evidence": "Repository gates pass on exact head"} + {"criterion": "AC-04", "commands": ["npm run verify", "./project/governance-check.sh", "make docker-smoke"], "evidence": "Repository gates pass on exact head"}, + {"criterion": "AC-05", "commands": ["node --test dist/test/workspace.test.js"], "evidence": "Comparison graph ceiling is greater than the observed 142557246-byte Platform graph and remains exactly bounded at 256 MiB"} ] } } diff --git a/src/comparison/workspace.ts b/src/comparison/workspace.ts index 9457838..1736a30 100644 --- a/src/comparison/workspace.ts +++ b/src/comparison/workspace.ts @@ -23,6 +23,13 @@ export const WORKSPACE_COMPARISON_DEADLINE_POLICY = Object.freeze({ maximumDeadlineMs: 40 * 60 * 1000, }); +// Generated graphs are denser than their source records. Platform currently +// produces a ~136 MiB graph, so the generic 128 MiB JSON ceiling rejects an +// artifact that the bounded pipeline has just produced. Keep a separate, +// explicit ceiling for the two comparison graphs instead of weakening the +// default limit for every JSON consumer. +export const WORKSPACE_COMPARISON_GRAPH_MAX_BYTES = 256 * 1024 * 1024; + export interface WorkspaceComparisonDeadlineLoad { inputBytes: number; llmWorkUnits: number; @@ -203,8 +210,8 @@ export async function compareWorkspaceIntent( throw error; } const [baseGraph, currentGraph, baseDiagnostics, currentDiagnostics] = await Promise.all([ - readJson(baseRun.graphPath), - readJson(currentRun.graphPath), + readJson(baseRun.graphPath, WORKSPACE_COMPARISON_GRAPH_MAX_BYTES), + readJson(currentRun.graphPath, WORKSPACE_COMPARISON_GRAPH_MAX_BYTES), readJson(baseRun.diagnosticsPath), readJson(currentRun.diagnosticsPath), ]); diff --git a/test/workspace.test.ts b/test/workspace.test.ts index c4acfc2..ac5ebca 100644 --- a/test/workspace.test.ts +++ b/test/workspace.test.ts @@ -9,6 +9,7 @@ import { calculateWorkspaceComparisonDeadline, classifyWorkspaceTrend, compareWorkspaceIntent, + WORKSPACE_COMPARISON_GRAPH_MAX_BYTES, } from '../src/comparison/workspace.js'; import { pathExists, readJson } from '../src/core/io.js'; import type { PipelineManifest } from '../src/core/types.js'; @@ -16,6 +17,12 @@ import { makeConfig } from './helpers.js'; const exec = promisify(execFile); +test('workspace comparison has a bounded graph ceiling above large Platform evidence', () => { + const observedPlatformGraphBytes = 142_557_246; + assert.ok(WORKSPACE_COMPARISON_GRAPH_MAX_BYTES > observedPlatformGraphBytes); + assert.equal(WORKSPACE_COMPARISON_GRAPH_MAX_BYTES, 256 * 1024 * 1024); +}); + test('workspace comparison deadline scales aggregate input and LLM work in bounded 2x steps', () => { const baseline = calculateWorkspaceComparisonDeadline({ inputBytes: 128 * 1024, llmWorkUnits: 16 }); assert.equal(baseline.multiplier, 1);