From b1014f36c91693061a841d0e11db5a7f4aa90b6c Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Thu, 15 Oct 2026 01:40:32 +0700 Subject: [PATCH] S00-013: Bound runner prompts with explicit required task input reads Changes: Keep startup instructions and exact context packets inline while listing supplementary task inputs as mandatory project reads. Preserve root containment, missing-artifact guidance and budget failures. Add S21-006 exact UI context regression and cover claim/review budgets for all tasks; leave stdin delivery unchanged. Validation: make check passed all 68 tests, including delayed UTF-8 stdin/EOF, timeout and terminal-transition checks. All 556 current prompts fit 80000 characters; largest 77693. git diff --check passed. Foundation checks do not establish application readiness. Task: S00-013 Agent: auto-ci-cd-5f68f03dd33b Role: ci-cd Action: claim Status: review Task title: Bound oversized S21-006 runner context without truncating requirements --- planning/TASK_MATRIX.md | 4 +-- planning/stages/S00.md | 2 +- planning/task_matrix.csv | 2 +- scripts/runner.py | 16 +++++++-- .../auto-ci-cd-5f68f03dd33b.txt | 4 +++ .../S00-013-auto-ci-cd-5f68f03dd33b.md | 27 ++++++++++++++ state/handoffs/S00-013.md | 8 +++++ state/tasks.json | 35 ++++++++++++++++--- tests/tooling/test_automation.py | 28 ++++++++++++++- 9 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 state/commit_messages/auto-ci-cd-5f68f03dd33b.txt create mode 100644 state/evidence/S00-013-auto-ci-cd-5f68f03dd33b.md create mode 100644 state/handoffs/S00-013.md diff --git a/planning/TASK_MATRIX.md b/planning/TASK_MATRIX.md index 3aff067..63ab0e9 100644 --- a/planning/TASK_MATRIX.md +++ b/planning/TASK_MATRIX.md @@ -1,6 +1,6 @@ # Матрица задач -Generated; state revision **14**. Canonical status: state/tasks.json. +Generated; state revision **16**. Canonical status: state/tasks.json. | ID | Этап | Оператор | Reviewer | Статус | Owner | Зависимости | Задача | | --- | --- | --- | --- | --- | --- | --- | --- | @@ -15,7 +15,7 @@ Generated; state revision **14**. Canonical status: state/tasks.json. | [S00-009](tasks/S00-009.md) | S00 | orchestrator | security | todo | | S00-003, S00-004, S00-005, S00-006, S00-007, S00-008 | Согласовать результаты spikes | | [S00-011](tasks/S00-011.md) | S00 | ci-cd | security | done | auto-ci-cd-d105e8027730 | S00-001 | Restore verified npm registry access for the stack spike | | [S00-012](tasks/S00-012.md) | S00 | ci-cd | qa | blocked | manual-ci-cd-stdin-20261015b | S00-001, S00-011, S00-013 | Fix runner prompt delivery after partial stdin timeout | -| [S00-013](tasks/S00-013.md) | S00 | ci-cd | qa | todo | | S00-001, S00-011 | Bound oversized S21-006 runner context without truncating requirements | +| [S00-013](tasks/S00-013.md) | S00 | ci-cd | qa | review | auto-ci-cd-5f68f03dd33b | S00-001, S00-011 | Bound oversized S21-006 runner context without truncating requirements | | [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 88fa231..8cf9a1d 100644 --- a/planning/stages/S00.md +++ b/planning/stages/S00.md @@ -17,7 +17,7 @@ - [S00-009](../tasks/S00-009.md): Согласовать результаты spikes — orchestrator; todo. - [S00-011](../tasks/S00-011.md): Restore verified npm registry access for the stack spike — ci-cd; done. - [S00-012](../tasks/S00-012.md): Fix runner prompt delivery after partial stdin timeout — ci-cd; blocked. -- [S00-013](../tasks/S00-013.md): Bound oversized S21-006 runner context without truncating requirements — ci-cd; todo. +- [S00-013](../tasks/S00-013.md): Bound oversized S21-006 runner context without truncating requirements — ci-cd; review. - [S00-010](../tasks/S00-010.md): Gate: Профиль и проверка стека — qa; todo. ## Граница этапа diff --git a/planning/task_matrix.csv b/planning/task_matrix.csv index 9141619..a20f0f1 100644 --- a/planning/task_matrix.csv +++ b/planning/task_matrix.csv @@ -10,7 +10,7 @@ S00-008,S00,ci-cd,qa,todo,,"S00-003, S00-004",Описать WSS/upload/TURN/pus S00-009,S00,orchestrator,security,todo,,"S00-003, S00-004, S00-005, S00-006, S00-007, S00-008",Согласовать результаты spikes S00-011,S00,ci-cd,security,done,auto-ci-cd-d105e8027730,S00-001,Restore verified npm registry access for the stack spike S00-012,S00,ci-cd,qa,blocked,manual-ci-cd-stdin-20261015b,"S00-001, S00-011, S00-013",Fix runner prompt delivery after partial stdin timeout -S00-013,S00,ci-cd,qa,todo,,"S00-001, S00-011",Bound oversized S21-006 runner context without truncating requirements +S00-013,S00,ci-cd,qa,review,auto-ci-cd-5f68f03dd33b,"S00-001, S00-011",Bound oversized S21-006 runner context without truncating requirements 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/scripts/runner.py b/scripts/runner.py index bc3ae6f..f7b431b 100644 --- a/scripts/runner.py +++ b/scripts/runner.py @@ -121,17 +121,27 @@ The coordinator commits each transition before launching another agent. ''' paths = ['AGENTS.md', 'README.md', 'master_prompt.md', 'roles/common.md', f'roles/{item["role"]}.md', 'docs/WEB_PROFILE.md', 'docs/ARCHITECTURE.md', 'docs/CONTRACTS.md', 'docs/WORKFLOW.md', 'docs/AUTOMATION.md'] - # Only bounded, concrete referenced upstream artifacts, never the entire repository. + # Task-specific inputs are explicit required reads, rather than whole + # documents duplicated beside the exact requirements in the packet. + # Keep startup instructions inline for every fresh session. + required_reads = [] for raw in task['inputs']: candidate = raw.split(' (')[0] - if candidate not in paths and (self.root / candidate).is_file(): - paths.append(candidate) + if not (self.root / candidate).resolve().is_relative_to(self.root): + raise ValueError('Prompt input escapes project root') + if candidate not in paths: + required_reads.append(raw) row = tracker.state()['tasks'][item['id']] if row.get('handoff'): paths.append(row['handoff']) if item['action'] == 'review' and row.get('evidence'): paths.append(row['evidence']) chunks = [assigned] + if required_reads: + chunks.append('\n# Required task input reads (not inlined)\n\n' + 'Before implementation or review, read these task inputs from the project. ' + 'Their contents are not included in this prompt; a missing required artifact is a blocker.\n\n' + + '\n'.join('- ' + raw for raw in required_reads)) for rel in dict.fromkeys(paths): path = (self.root / rel).resolve() if not path.is_relative_to(self.root): diff --git a/state/commit_messages/auto-ci-cd-5f68f03dd33b.txt b/state/commit_messages/auto-ci-cd-5f68f03dd33b.txt new file mode 100644 index 0000000..fb29d63 --- /dev/null +++ b/state/commit_messages/auto-ci-cd-5f68f03dd33b.txt @@ -0,0 +1,4 @@ +Bound runner prompts with explicit required task input reads + +Changes: Keep startup instructions and exact context packets inline while listing supplementary task inputs as mandatory project reads. Preserve root containment, missing-artifact guidance and budget failures. Add S21-006 exact UI context regression and cover claim/review budgets for all tasks; leave stdin delivery unchanged. +Validation: make check passed all 68 tests, including delayed UTF-8 stdin/EOF, timeout and terminal-transition checks. All 556 current prompts fit 80000 characters; largest 77693. git diff --check passed. Foundation checks do not establish application readiness. diff --git a/state/evidence/S00-013-auto-ci-cd-5f68f03dd33b.md b/state/evidence/S00-013-auto-ci-cd-5f68f03dd33b.md new file mode 100644 index 0000000..5b3850f --- /dev/null +++ b/state/evidence/S00-013-auto-ci-cd-5f68f03dd33b.md @@ -0,0 +1,27 @@ +# S00-013 executor evidence + +Agent: auto-ci-cd-5f68f03dd33b; role: ci-cd; date: 2026-10-15. +Result: bounded context preparation; pending independent QA review. + +Input: assigned task/card/context, NFR-007, workflow/role instructions, S00-012/013 blocker reports, accepted scope ADR and S00-001/S00-011 dependency evidence/reviews/handoffs. Output: one runner context correction and focused regressions. No contracts or stack decisions changed. + +## Actual change and reasoning + +S21-006 packet is 41660 characters and includes all 26 exact UI Kit sections. The old runner additionally embedded entire input documents, including the 11760-character stack ADR. Startup documents plus this packet and task inputs exceeded the 80000-character budget. + +Runner now keeps assignment/startup instructions, exact packet, previous handoff and review evidence inline. Other task inputs are listed explicitly as required project reads before implementation/review, preserving their path annotations and missing-artifact blocker instruction. This also makes missing upstream inputs visible instead of silently omitting them. Project-root path checking remains enforced for referenced inputs. No text is sliced, no spec/packet is edited, and both packet and prompt budget guards remain active. The stdin transport implementation is untouched. + +The S21-006 regression checks both executor and reviewer prompts, the whole exact packet, every verbatim UI Kit section, required input references and fresh-session/exit instructions. The all-current-prompts check now covers both actions for every task. + +## Actual commands and results + +- `python3 scripts/tasks.py resume --agent auto-ci-cd-5f68f03dd33b` and `show S00-013`: exit 0; already assigned in_progress, no repeat claim. +- `python3 scripts/tasks.py packet S00-013 --agent auto-ci-cd-5f68f03dd33b > /private/tmp/luma-S00-013-packet.md`: exit 0. +- Initial automation run of the first draft: exit 1, 23/24 tests passed; review prompt still exceeded budget when only upstream-annotated artifacts were deferred. Corrected by consistently referencing all supplementary task inputs, keeping startup instructions inline. +- Read-only Python enumeration using Runner with default config: exit 0; all 556 claim/review prompts for 278 tasks fit; largest S21-006 review 77693 characters, claim 77669 (agent auto-preview). +- `make check`: exit 0, 68 tests passed. Final rerun after project-root guard: exit 0, 68 tests in 16.124s; validated 278 tasks, 22 stages, 221 requirements, 211 allocated Web requirements, revision 15. Includes delayed large UTF-8 stdin/EOF delivery, timeout, terminal-transition, orchestration, snapshot and CLI checks. Log: temporary /private/tmp/luma-S00-013-check.log. +- `git diff --check`: exit 0; source diff inspected, limited to scripts/runner.py and tests/tooling/test_automation.py. Initial state/tasks.json change was coordinator claim metadata. + +## Limits + +These are foundation/harness checks, not app readiness or S00-002 acceptance. Agents must actually read the explicitly listed project inputs; references do not claim those artifacts were read automatically. Budget coverage describes current task/state artifacts; future larger evidence/handoffs still fail explicitly rather than truncate. No dependencies, credentials, production transports or immutable spec snapshots changed. Coordinator owns commit and the next fresh reviewer process. diff --git a/state/handoffs/S00-013.md b/state/handoffs/S00-013.md new file mode 100644 index 0000000..c7c34eb --- /dev/null +++ b/state/handoffs/S00-013.md @@ -0,0 +1,8 @@ +# S00-013 handoff + +Executor: auto-ci-cd-5f68f03dd33b (ci-cd). +Result: runner references supplementary task inputs as explicit required project reads, retaining startup instructions, exact context packet, handoff and review evidence inline. No truncation or budget increase; stdin transport unchanged. + +Ready for QA review. Inspect scripts/runner.py and tests/tooling/test_automation.py, compare commit message/evidence, run `make check`. Focus on S21-006 executor/reviewer preserving all exact requirements and 26 UI Kit sections, explicit read-before-work/missing-artifact instructions, and all-current-prompts budget check (now both actions). All 556 current prompts fit 80000; maximum 77693. Final make check: 68 tests passed, exit 0, including delayed UTF-8 stdin, timeout and terminal-transition checks. + +Evidence: state/evidence/S00-013-auto-ci-cd-5f68f03dd33b.md. Task-specific documents remain mandatory reads from disk. Future larger handoffs/evidence remain subject to fail-fast budgets. No app readiness or parent-task acceptance claimed. Reviewer must independently approve/reject; coordinator commits transition and launches next fresh session. Executor does not set done or continue S00-012. diff --git a/state/tasks.json b/state/tasks.json index fb53c8c..f5aadff 100644 --- a/state/tasks.json +++ b/state/tasks.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "revision": 14, + "revision": 16, "tasks": { "S00-001": { "status": "done", @@ -1150,10 +1150,14 @@ "handoff": "state/handoffs/S00-012.md" }, "S00-013": { - "status": "todo", - "owner": null, + "status": "review", + "owner": "auto-ci-cd-5f68f03dd33b", "external_wait": false, - "reason": null + "reason": null, + "started_at": "2026-10-14T18:37:37+00:00", + "updated_at": "2026-10-14T18:40:32+00:00", + "evidence": "state/evidence/S00-013-auto-ci-cd-5f68f03dd33b.md", + "handoff": "state/handoffs/S00-013.md" } }, "events": [ @@ -1324,6 +1328,29 @@ "from": "in_progress", "to": "blocked", "reason": "Required automation suite fails in existing all-prompts budget test: S21-006 exceeds even a diagnostic 90000-character prompt limit. This blocks verification of the stdin remediation; production limit remains 80000." + }, + { + "revision": 15, + "at": "2026-10-14T18:37:37+00:00", + "action": "claim", + "task": "S00-013", + "agent": "auto-ci-cd-5f68f03dd33b", + "role": "ci-cd", + "from": "todo", + "to": "in_progress", + "reason": null + }, + { + "revision": 16, + "at": "2026-10-14T18:40:32+00:00", + "action": "submit", + "task": "S00-013", + "agent": "auto-ci-cd-5f68f03dd33b", + "role": null, + "from": "in_progress", + "to": "review", + "reason": null, + "evidence": "state/evidence/S00-013-auto-ci-cd-5f68f03dd33b.md" } ], "retired_agents": [ diff --git a/tests/tooling/test_automation.py b/tests/tooling/test_automation.py index 29749e3..c1a90aa 100644 --- a/tests/tooling/test_automation.py +++ b/tests/tooling/test_automation.py @@ -281,11 +281,37 @@ else: class FoundationRunnerTests(unittest.TestCase): + def test_ui_acceptance_prompt_keeps_exact_context_and_explicit_upstream_reads(self): + runner = RUN_MODULE.Runner(ROOT, {}) + task = runner.tracker.task('S21-006') + for action, role in [('claim', task['role']), ('review', task['reviewer_role'])]: + with self.subTest(action=action): + prompt = runner.prompt({'id': task['id'], 'role': role, 'action': action}, 'auto-preview') + self.assertLessEqual(len(prompt), 80000) + self.assertIn(runner.tracker.packet(task['id'], 'auto-preview'), prompt) + self.assertIn('Required task input reads (not inlined)', prompt) + self.assertIn('Before implementation or review, read these task inputs', prompt) + self.assertIn('a missing required artifact is a blocker', prompt) + for raw in task['inputs']: + self.assertIn(raw, prompt) + if ' (upstream artifact' in raw: + self.assertIn('- ' + raw, prompt) + self.assertNotIn('# File: ' + raw.split(' (')[0] + '\n', prompt) + # Every UI Kit section stays verbatim, including tables and + # unnumbered details beyond the short requirement registry. + spec = (ROOT / 'specs/uikit_clear.md').read_text(encoding='utf-8') + for section in task['ui_sections']: + self.assertIn(runner.tracker.section(spec, section), prompt) + self.assertIn('This is a fresh session.', prompt) + self.assertIn('After submit/approve/reject EXIT.', prompt) + def test_all_current_fresh_agent_prompts_fit_configured_budget(self): runner = RUN_MODULE.Runner(ROOT, {}) lengths = [] for task in runner.tracker.definitions()['tasks']: - lengths.append(len(runner.prompt({'id': task['id'], 'role': task['role'], 'action': 'claim'}, 'auto-preview'))) + for action, role in [('claim', task['role']), ('review', task['reviewer_role'])]: + with self.subTest(task=task['id'], action=action): + lengths.append(len(runner.prompt({'id': task['id'], 'role': role, 'action': action}, 'auto-preview'))) self.assertLessEqual(max(lengths), 80000) def test_unconfigured_runner_does_not_claim_product_work(self):