tumwater 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -28
- package/dist/build-info.json +2 -2
- package/dist/src/agent/agent-args.js +24 -0
- package/dist/src/agent/agent-backend.js +2 -2
- package/dist/src/agent/backend-traits.js +60 -0
- package/dist/src/agent/claude/claude-account.js +61 -8
- package/dist/src/agent/claude/claude-args.js +12 -15
- package/dist/src/agent/claude/claude-backend.js +51 -41
- package/dist/src/agent/claude/claude-env.js +7 -3
- package/dist/src/agent/claude/claude-stream.js +7 -16
- package/dist/src/agent/image-input.js +107 -0
- package/dist/src/agent/notes-shim.js +41 -0
- package/dist/src/agent/opencode/opencode-args.js +61 -0
- package/dist/src/agent/opencode/opencode-backend.js +255 -0
- package/dist/src/agent/opencode/opencode-catalog.js +184 -0
- package/dist/src/agent/opencode/opencode-config.js +188 -0
- package/dist/src/agent/opencode/opencode-env.js +36 -0
- package/dist/src/agent/opencode/opencode-session-id.js +37 -0
- package/dist/src/agent/opencode/opencode-stream.js +278 -0
- package/dist/src/agent/role-notes-write.js +16 -32
- package/dist/src/agent/run-agent.js +95 -18
- package/dist/src/agent/session-ledger.js +57 -1
- package/dist/src/backlog/backlog-archive.js +296 -0
- package/dist/src/backlog/backlog-cli.js +573 -0
- package/dist/src/backlog/backlog-eligibility.js +332 -43
- package/dist/src/backlog/backlog-md.js +79 -17
- package/dist/src/backlog/backlog-render.js +62 -11
- package/dist/src/backlog/backlog-structure.js +261 -58
- package/dist/src/backlog/backlog-write.js +178 -441
- package/dist/src/backlog/backlog.js +113 -16
- package/dist/src/backlog/question-answer.js +339 -0
- package/dist/src/baseline/main-baseline.js +75 -88
- package/dist/src/baseline/main-red.js +32 -30
- package/dist/src/{brief-edit.js → brief/brief-edit.js} +12 -11
- package/dist/src/{brief.js → brief/brief.js} +33 -8
- package/dist/src/budget/budget.js +32 -15
- package/dist/src/budget/fallback-breaker.js +8 -7
- package/dist/src/build/build-check-detect.js +8 -7
- package/dist/src/build/build-check-events.js +68 -22
- package/dist/src/build/build-check-report.js +22 -23
- package/dist/src/build/build-check-scoped.js +51 -62
- package/dist/src/build/build-check.js +15 -14
- package/dist/src/build/build-info.js +2 -1
- package/dist/src/build/build-stage.js +23 -22
- package/dist/src/build/dep-install.js +22 -21
- package/dist/src/build/host-sleep.js +1 -1
- package/dist/src/change/change-data.js +13 -11
- package/dist/src/change/change-render.js +11 -10
- package/dist/src/cli/brief-command.js +9 -7
- package/dist/src/cli/cli-args.js +25 -5
- package/dist/src/cli/cli-command-args.js +43 -10
- package/dist/src/cli/cli-editor.js +13 -1
- package/dist/src/cli/cli-flag-specs.js +31 -6
- package/dist/src/cli/cli-marker-commands.js +13 -10
- package/dist/src/cli/cli-query-commands.js +439 -56
- package/dist/src/cli/cli-repo-gate.js +1 -1
- package/dist/src/cli/cli-run.js +124 -68
- package/dist/src/cli/completion.js +70 -12
- package/dist/src/cli/config-commands.js +14 -11
- package/dist/src/cli/help.js +264 -124
- package/dist/src/cli/log-commands.js +127 -21
- package/dist/src/cli/notify-command.js +33 -18
- package/dist/src/cli/question-commands.js +13 -224
- package/dist/src/cli.js +78 -36
- package/dist/src/collections.js +66 -16
- package/dist/src/concurrency/check-permit.js +16 -17
- package/dist/src/concurrency/lock.js +6 -5
- package/dist/src/concurrency/provider-lease.js +69 -0
- package/dist/src/concurrency/semaphore.js +258 -36
- package/dist/src/config/config-aliases.js +106 -0
- package/dist/src/config/config-editable-keys.js +3 -3
- package/dist/src/config/config-fallbacks.js +379 -0
- package/dist/src/config/config-field-checks.js +19 -10
- package/dist/src/config/config-keys.js +160 -0
- package/dist/src/config/config-live.js +64 -12
- package/dist/src/config/config-schema.js +34 -22
- package/dist/src/config/config-validation.js +132 -48
- package/dist/src/config/config-views.js +107 -325
- package/dist/src/config/config-write.js +138 -177
- package/dist/src/config/config.js +60 -49
- package/dist/src/config/model-selector.js +28 -2
- package/dist/src/doctor/doctor-backlog.js +494 -68
- package/dist/src/doctor/doctor-checks.js +509 -58
- package/dist/src/doctor/doctor-holds.js +139 -78
- package/dist/src/doctor/doctor-install.js +30 -0
- package/dist/src/doctor/doctor-launch-services.js +2 -2
- package/dist/src/doctor/doctor-model-checks.js +549 -157
- package/dist/src/doctor/doctor-notify.js +2 -3
- package/dist/src/doctor/doctor-orphans.js +10 -9
- package/dist/src/doctor/doctor-render.js +36 -9
- package/dist/src/doctor/doctor.js +76 -25
- package/dist/src/doctor/image-probe.js +244 -0
- package/dist/src/doctor/probe.js +64 -0
- package/dist/src/events/event-format.js +219 -106
- package/dist/src/events/event-labels.js +116 -0
- package/dist/src/events/event-legacy.js +140 -0
- package/dist/src/events/event-read.js +58 -22
- package/dist/src/events/event-window.js +27 -7
- package/dist/src/events/events.js +18 -14
- package/dist/src/events/notify.js +80 -30
- package/dist/src/failure/failure-cluster.js +12 -9
- package/dist/src/failure/failure-data.js +96 -48
- package/dist/src/failure/failure-render.js +69 -58
- package/dist/src/failure/failure-state-change.js +33 -26
- package/dist/src/failure/time-spend.js +79 -59
- package/dist/src/files/file-queue.js +16 -4
- package/dist/src/files/files.js +18 -6
- package/dist/src/files/json-object.js +18 -3
- package/dist/src/files/tail.js +1 -1
- package/dist/src/gates/bootstrap-gates.js +5 -4
- package/dist/src/gates/budget-gates.js +250 -34
- package/dist/src/gates/disk-gate.js +18 -18
- package/dist/src/gates/gate-polls.js +117 -69
- package/dist/src/gates/maintenance-quota.js +29 -29
- package/dist/src/gates/pause-gates.js +11 -11
- package/dist/src/gates/readiness.js +2 -1
- package/dist/src/gates/role-cap-gates.js +16 -21
- package/dist/src/gates/startup-gate.js +75 -31
- package/dist/src/gates/streak-gate.js +18 -16
- package/dist/src/git/commit-message.js +6 -5
- package/dist/src/git/git-diff.js +16 -16
- package/dist/src/git/git-run.js +8 -8
- package/dist/src/git/git.js +79 -59
- package/dist/src/git/slots-state.js +14 -5
- package/dist/src/git/worktree-pool.js +25 -18
- package/dist/src/git/worktree-use.js +15 -14
- package/dist/src/git/worktree.js +18 -18
- package/dist/src/gui/gui-args.js +10 -14
- package/dist/src/gui/gui-backlog-commands.js +273 -0
- package/dist/src/gui/gui-command.js +1 -1
- package/dist/src/gui/gui-config-commands.js +440 -0
- package/dist/src/gui/gui-endpoint-commands.js +16 -716
- package/dist/src/gui/gui-endpoint-common.js +49 -0
- package/dist/src/gui/gui-endpoints.js +105 -54
- package/dist/src/gui/gui-operator-commands.js +145 -0
- package/dist/src/gui/gui-prompt-commands.js +234 -0
- package/dist/src/gui/gui-server.js +25 -8
- package/dist/src/gui/gui-team-commands.js +164 -0
- package/dist/src/gui/http-body.js +17 -1
- package/dist/src/history/history-data.js +179 -104
- package/dist/src/history/history-render.js +76 -0
- package/dist/src/history/history.js +29 -70
- package/dist/src/inbox/inbox-attachments.js +66 -10
- package/dist/src/inbox/inbox-cancel.js +7 -5
- package/dist/src/inbox/inbox-edit.js +1 -1
- package/dist/src/inbox/inbox-submit.js +44 -4
- package/dist/src/inbox/inbox-top.js +83 -0
- package/dist/src/inbox/inbox.js +8 -2
- package/dist/src/inbox/pending-prompt.js +1 -1
- package/dist/src/inbox/prompt-commands.js +114 -73
- package/dist/src/init/init-templates.js +16 -14
- package/dist/src/init/init.js +12 -11
- package/dist/src/loop/leftover.js +28 -27
- package/dist/src/loop/loop-fallback.js +2 -2
- package/dist/src/loop/loop-pi.js +104 -50
- package/dist/src/loop/loop-recovery.js +15 -15
- package/dist/src/loop/loop-state.js +130 -13
- package/dist/src/loop/loop-tick.js +190 -88
- package/dist/src/loop/loop.js +68 -36
- package/dist/src/loop/model-fallback.js +3 -2
- package/dist/src/loop/revision.js +16 -7
- package/dist/src/merge/backlog-conflicts.js +155 -0
- package/dist/src/{landing/landing-batch.js → merge/merge-batch.js} +90 -89
- package/dist/src/{landing/landing-check-failures.js → merge/merge-check-failures.js} +87 -41
- package/dist/src/{landing/landing-core.js → merge/merge-core.js} +119 -95
- package/dist/src/{landing/landing-diff.js → merge/merge-diff.js} +1 -1
- package/dist/src/merge/merge-drain.js +212 -0
- package/dist/src/{landing/landing-git.js → merge/merge-git.js} +94 -20
- package/dist/src/merge/merge-pipeline.js +99 -0
- package/dist/src/{landing/landing-questions.js → merge/merge-questions.js} +9 -6
- package/dist/src/merge/merge-queue-render.js +75 -0
- package/dist/src/{landing/landing-queue.js → merge/merge-queue.js} +95 -36
- package/dist/src/merge/merge-slot.js +340 -0
- package/dist/src/{landing/landing-stack.js → merge/merge-stack.js} +66 -62
- package/dist/src/{landing/landing-merge.js → merge/merge-to-main.js} +72 -62
- package/dist/src/merge/merge-verify.js +212 -0
- package/dist/src/notes-cli.js +97 -0
- package/dist/src/operator/operator-commands.js +113 -45
- package/dist/src/operator/operator-intent.js +74 -53
- package/dist/src/operator/operator-requests.js +52 -52
- package/dist/src/operator/retire.js +47 -28
- package/dist/src/operator/revert.js +71 -0
- package/dist/src/orchestrator/orchestrator-launch.js +74 -14
- package/dist/src/orchestrator/orchestrator-scheduling.js +74 -43
- package/dist/src/orchestrator/orchestrator.js +149 -96
- package/dist/src/orchestrator/retention.js +29 -12
- package/dist/src/orchestrator/startup-migration-steps.js +51 -0
- package/dist/src/orchestrator/startup-migrations.js +40 -0
- package/dist/src/paths.js +124 -38
- package/dist/src/pi/pi-args.js +26 -3
- package/dist/src/pi/pi-backend.js +15 -23
- package/dist/src/pi/pi-bin.js +18 -12
- package/dist/src/pi/pi-event-line.js +17 -1
- package/dist/src/pi/pi-failure.js +87 -0
- package/dist/src/pi/pi-models.js +126 -38
- package/dist/src/pi/pi-run-result.js +1 -1
- package/dist/src/pi/pi-settings.js +86 -0
- package/dist/src/pi/pi-stream.js +131 -107
- package/dist/src/pi/pi-watchdogs.js +4 -3
- package/dist/src/pi-extension/bounded-output.js +20 -5
- package/dist/src/pi-extension/context-budget.js +3 -1
- package/dist/src/pi-extension/context-shake.js +54 -21
- package/dist/src/pi-extension/context-window.js +37 -0
- package/dist/src/pi-extension/full-output.js +2 -2
- package/dist/src/pi-extension/strip-thinking.js +80 -0
- package/dist/src/pi-extension/trim-system-prompt.js +38 -0
- package/dist/src/process/launch-services.js +11 -10
- package/dist/src/process/process-table.js +1 -1
- package/dist/src/process/process.js +7 -7
- package/dist/src/process/run-marker.js +29 -6
- package/dist/src/process/supervisor.js +36 -25
- package/dist/src/prompt/dialect.js +30 -10
- package/dist/src/prompt/gate-prompts.js +170 -67
- package/dist/src/prompt/principles.js +1 -0
- package/dist/src/prompt/prompt-followup.js +29 -20
- package/dist/src/prompt/prompt.js +249 -91
- package/dist/src/redeploy/redeploy-policy.js +10 -10
- package/dist/src/redeploy/redeploy.js +6 -4
- package/dist/src/redeploy/redeployer.js +63 -55
- package/dist/src/redeploy/self-reload.js +1 -1
- package/dist/src/report/report-data.js +259 -254
- package/dist/src/report/report-fold.js +353 -0
- package/dist/src/report/report-render.js +235 -44
- package/dist/src/request-timeouts.js +1 -1
- package/dist/src/review/known-flakes.js +34 -14
- package/dist/src/review/protected-edits.js +4 -3
- package/dist/src/review/review-followup.js +16 -4
- package/dist/src/review/review-precheck.js +14 -13
- package/dist/src/review/review-verdict.js +14 -0
- package/dist/src/review/review.js +55 -34
- package/dist/src/review/secret-leaks.js +127 -0
- package/dist/src/review/suite-rerun.js +4 -3
- package/dist/src/roles/legacy-role-ids.js +21 -0
- package/dist/src/roles/legacy-role-migration.js +62 -0
- package/dist/src/roles/loop-ids.js +19 -2
- package/dist/src/roles/role-catalog.js +109 -131
- package/dist/src/roles/role-guidance.js +64 -31
- package/dist/src/roles/role-labels.js +10 -0
- package/dist/src/roles/role-render.js +194 -18
- package/dist/src/roles/role-view.js +216 -17
- package/dist/src/roles/roles.js +16 -14
- package/dist/src/scheduling/backoff.js +29 -19
- package/dist/src/scheduling/claims.js +15 -8
- package/dist/src/scheduling/once-round.js +11 -11
- package/dist/src/scheduling/quiet-hours.js +25 -32
- package/dist/src/scheduling/scheduling.js +28 -25
- package/dist/src/scheduling/{work-landed-cache.js → work-merged-cache.js} +14 -14
- package/dist/src/status/status-budget.js +115 -0
- package/dist/src/status/status-data.js +72 -184
- package/dist/src/status/status-inbox.js +47 -0
- package/dist/src/status/status-install.js +27 -0
- package/dist/src/status/status-polls.js +50 -39
- package/dist/src/status/status-roles.js +105 -0
- package/dist/src/{fleet → team}/error-storm.js +10 -10
- package/dist/src/{fleet → team}/failure-spread.js +8 -8
- package/dist/src/{fleet → team}/orchestrator-info.js +84 -18
- package/dist/src/{fleet → team}/reclaim.js +5 -4
- package/dist/src/{fleet/fleet-hold.js → team/team-hold.js} +55 -21
- package/dist/src/{fleet/fleet-polls.js → team/team-polls.js} +116 -65
- package/dist/src/{fleet/fleet-state.js → team/team-state.js} +39 -38
- package/dist/src/text/datetime.js +42 -2
- package/dist/src/text/format.js +10 -1
- package/dist/src/text/markdown.js +1 -1
- package/dist/src/text/phrases.js +35 -34
- package/dist/src/text/suggest.js +3 -2
- package/dist/src/text/text.js +2 -2
- package/dist/src/tick/qa-coverage.js +2 -1
- package/dist/src/tick/stage-check.js +142 -25
- package/dist/src/tick/telemetry-digest.js +10 -9
- package/dist/src/tick/tick-apply.js +101 -72
- package/dist/src/tick/tick-detail-data.js +23 -22
- package/dist/src/tick/tick-detail.js +37 -24
- package/dist/src/tick/tick-finalize.js +29 -22
- package/dist/src/tick/tick-outcome.js +2 -1
- package/dist/src/tick/tick-prompt.js +94 -26
- package/dist/src/tick/tick-resume.js +29 -13
- package/dist/src/tick/tick-stage.js +67 -53
- package/dist/src/tick/tick-timing.js +60 -59
- package/dist/src/tick/tick-usage.js +53 -23
- package/dist/src/tick/tick-verdict.js +75 -10
- package/dist/src/ui/badges.js +113 -69
- package/dist/src/ui/gui/gui-client-boot.js +202 -29
- package/dist/src/ui/gui/gui-client-composer.js +102 -23
- package/dist/src/ui/gui/gui-client-drawer.js +330 -75
- package/dist/src/ui/gui/gui-client-history.js +94 -37
- package/dist/src/ui/gui/gui-client-labels.js +24 -0
- package/dist/src/ui/gui/gui-client-loops.js +90 -47
- package/dist/src/ui/gui/gui-client-markdown.js +1 -0
- package/dist/src/ui/gui/gui-client-model.js +60 -43
- package/dist/src/ui/gui/gui-client-operator.js +73 -43
- package/dist/src/ui/gui/gui-client-pending.js +34 -31
- package/dist/src/ui/gui/gui-client-report.js +330 -47
- package/dist/src/ui/gui/gui-client-settings.js +126 -18
- package/dist/src/ui/gui/gui-client-sound.js +2 -1
- package/dist/src/ui/gui/{gui-client-fleet.js → gui-client-team.js} +190 -74
- package/dist/src/ui/gui/gui-client.js +26 -20
- package/dist/src/ui/gui/gui-page.js +18 -19
- package/dist/src/ui/gui/gui-styles.js +12 -4
- package/dist/src/ui/progress-data.js +5 -3
- package/dist/src/ui/status-model.js +176 -102
- package/dist/src/ui/status-payload.js +114 -36
- package/dist/src/ui/status-render.js +121 -52
- package/dist/src/ui/team-alerts.js +341 -0
- package/dist/src/ui/tick-progress-model.js +14 -14
- package/dist/src/ui/tone.js +9 -8
- package/dist/src/ui/transcript-tail.js +1 -0
- package/dist/src/ui/transcript.js +23 -16
- package/dist/src/ui/tui/tui-app.js +1 -0
- package/dist/src/ui/tui/tui-backlog.js +85 -11
- package/dist/src/ui/tui/tui-editor-answer.js +97 -0
- package/dist/src/ui/tui/tui-editor-attach.js +107 -0
- package/dist/src/ui/tui/tui-editor-brief.js +107 -0
- package/dist/src/ui/tui/tui-editor-budget.js +155 -0
- package/dist/src/ui/tui/tui-editor-ctx.js +1 -0
- package/dist/src/ui/tui/tui-editor-entry.js +230 -0
- package/dist/src/ui/tui/tui-editor-interval.js +122 -0
- package/dist/src/ui/tui/tui-editor-notes.js +114 -0
- package/dist/src/ui/tui/tui-editor-pause.js +266 -0
- package/dist/src/ui/tui/tui-editor-prompt.js +95 -0
- package/dist/src/ui/tui/tui-editor-queued.js +98 -0
- package/dist/src/ui/tui/tui-editor-quiet.js +106 -0
- package/dist/src/ui/tui/tui-editor-retire.js +83 -0
- package/dist/src/ui/tui/tui-editor-search.js +73 -0
- package/dist/src/ui/tui/tui-editor-session.js +97 -0
- package/dist/src/ui/tui/tui-editors.js +152 -0
- package/dist/src/ui/tui/tui-frame.js +61 -57
- package/dist/src/ui/tui/tui-history.js +12 -7
- package/dist/src/ui/tui/tui-input.js +44 -50
- package/dist/src/ui/tui/tui-keymap.js +1 -0
- package/dist/src/ui/tui/tui-keys.js +87 -1821
- package/dist/src/ui/tui/tui-pane-activity.js +99 -0
- package/dist/src/ui/tui/tui-pane-backlog.js +224 -0
- package/dist/src/ui/tui/tui-pane-brief.js +30 -0
- package/dist/src/ui/tui/tui-pane-ctx.js +11 -0
- package/dist/src/ui/tui/tui-pane-health.js +124 -0
- package/dist/src/ui/tui/tui-pane-history.js +316 -0
- package/dist/src/ui/tui/tui-pane-pending.js +74 -0
- package/dist/src/ui/tui/tui-pane-queued.js +143 -0
- package/dist/src/ui/tui/tui-pane-report.js +122 -0
- package/dist/src/ui/tui/tui-pane-session.js +101 -0
- package/dist/src/ui/tui/tui-pane-transcript.js +150 -0
- package/dist/src/ui/tui/tui-pane.js +52 -28
- package/dist/src/ui/tui/tui-panes.js +294 -0
- package/dist/src/ui/tui/tui.js +44 -26
- package/dist/src/verdict/fix-claim.js +56 -33
- package/dist/src/verdict/no-change.js +19 -0
- package/dist/src/verdict/refusal.js +43 -11
- package/dist/src/verdict/reply-contract.js +17 -5
- package/dist/src/version.js +3 -2
- package/package.json +4 -2
- package/dist/src/agent/mcp/role-notes-server.js +0 -160
- package/dist/src/landing/backlog-conflicts.js +0 -116
- package/dist/src/landing/landing-drain.js +0 -204
- package/dist/src/landing/landing-pipeline.js +0 -96
- package/dist/src/landing/landing-queue-render.js +0 -56
- package/dist/src/landing/landing-slot.js +0 -256
- package/dist/src/landing/landing-vetting.js +0 -196
- package/dist/src/pi-extension/role-notes.js +0 -40
- package/dist/src/ui/fleet-alerts.js +0 -174
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
// vocabulary: plain
|
|
1
2
|
/** The role catalog: one built-in loop's identity and its role-specific "find something to do"
|
|
2
3
|
* instruction text. Split out of roles.ts (2026-10-01, organize) so the catalog's embedded
|
|
3
4
|
* prompt prose lives apart from the derived registries and classification helpers, which stayed
|
|
4
5
|
* in roles.ts. Pure catalog data — the shared instruction fragments role prompts embed live in
|
|
5
6
|
* role-guidance.ts (import-only downward, so prompt assembly depends on both without a cycle).
|
|
6
7
|
* roles.ts re-exports ROLES and Role, so every existing importer keeps its import path. */
|
|
7
|
-
import { backlogMoveGuidance, DECOMPOSITION_GUIDANCE, NEEDS_REPLAN_NOTE, NEEDS_REVIEW_NOTE, PLAN_SIZING, searchGuidance, VALIDATION_GAP_GUIDANCE, VALIDATION_GAP_TALLY, } from "./role-guidance.js";
|
|
8
|
+
import { backlogMoveGuidance, DECOMPOSITION_GUIDANCE, NEEDS_REPLAN_NOTE, NEEDS_REVIEW_NOTE, PLAN_SIZING, searchGuidance, VALIDATION_GAP_GUIDANCE, VALIDATION_GAP_QUERY, VALIDATION_GAP_TALLY, WAITING_FOR_FAILURE_NOTE, WAITING_FOR_FAILURE_PREFIX, } from "./role-guidance.js";
|
|
9
|
+
import { roleCommitGrep } from "./legacy-role-ids.js";
|
|
8
10
|
import { NOTHING_TO_DO } from "../verdict/reply-contract.js";
|
|
11
|
+
/** The trailer the readme role's commits carry and its `git log --grep` reads back; git parses
|
|
12
|
+
* it, so it keeps this spelling. Interpolated because a comment inside the template would
|
|
13
|
+
* become prompt text. */
|
|
14
|
+
const README_TRAILER = "Run: readme #";
|
|
15
|
+
const README_TRAILER_GREP = "^(Run|Tick): readme #"; // vocabulary-ok: legacy name read from old refs or commits
|
|
16
|
+
const README_TRAILER_LEGACY = "Tick: readme #"; // vocabulary-ok: legacy name read from old refs or commits
|
|
9
17
|
/** The opinionated role catalog. Every loop runs one role; a role's `find` text is
|
|
10
18
|
* the role-specific "find something to do" half of the tick prompt.
|
|
11
19
|
*
|
|
@@ -20,8 +28,9 @@ export const ROLES = [
|
|
|
20
28
|
1. The prompt's <backlog-index> block lists PLANS.md's \`## Planned\` entries with each
|
|
21
29
|
entry's line range; read the one you pick by that range.
|
|
22
30
|
2. Pick one entry under \`## Planned\`, preferring ones marked ready or with a written plan.
|
|
23
|
-
Skip entries the index block marks \`[blocked: …]\`
|
|
24
|
-
\`[refused]
|
|
31
|
+
Skip entries the index block marks \`[blocked: …]\` — \`[blocked: requires …]\` (a
|
|
32
|
+
prerequisite has not merged), \`[blocked: refused]\`, \`[blocked: needs review]\` or
|
|
33
|
+
\`[blocked: needs replan]\`. Skip plans whose entry carries a Refused note, and skip
|
|
25
34
|
entries already carrying a **Needs review …** note or a ${NEEDS_REPLAN_NOTE}. If PLANS.md
|
|
26
35
|
is empty or everything is done, there is nothing to do.
|
|
27
36
|
3. Read only the chosen entry's line range and the code it names.
|
|
@@ -33,7 +42,7 @@ export const ROLES = [
|
|
|
33
42
|
the entry's files-touched list and acceptance criteria, so land everything the entry
|
|
34
43
|
promises, or update the entry to say what changed and why. When a plan's anchors no longer
|
|
35
44
|
match the code, correct the entry in the same change instead of refusing.
|
|
36
|
-
6. Mark the plan done in PLANS.md — ${backlogMoveGuidance("PLANS.md", "## Planned", "## Done")}
|
|
45
|
+
6. Mark the plan done in PLANS.md — ${backlogMoveGuidance("PLANS.md", "## Planned", "## Done", "PLANS-DONE.md")}
|
|
37
46
|
7. Verify last, after the PLANS.md edit, so one run of the project's check covers everything
|
|
38
47
|
you changed (see "Leave the project working" below).
|
|
39
48
|
A plan that resists implementation is a finding: refuse it with the objection recorded rather
|
|
@@ -45,13 +54,16 @@ than forcing it.`,
|
|
|
45
54
|
title: "bug fixer",
|
|
46
55
|
find: `Fix the SINGLE most important open bug in BUGS.md.
|
|
47
56
|
1. The prompt's <backlog-index> block lists BUGS.md's \`## Open\` entries with each entry's
|
|
48
|
-
line range; read the one you pick by that range. Skip BUGS.md entries
|
|
49
|
-
note: when every open entry
|
|
57
|
+
line range; read the one you pick by that range. Skip BUGS.md entries the index block marks
|
|
58
|
+
\`[blocked: …]\` (such as \`[blocked: refused]\`, for a Refused note): when every open entry is marked, there is nothing to do. When \`## Open\` holds no entries at all, skip to the
|
|
50
59
|
latent-bug hunt at the end instead.
|
|
51
|
-
2. Reproduce it if possible: a failing test or a scratch script.
|
|
60
|
+
2. Reproduce it if possible: a failing test or a scratch script. When it cannot be reproduced
|
|
61
|
+
and this run made its failure message name the cause next time (or found it already does),
|
|
62
|
+
record a Progress note, write ${WAITING_FOR_FAILURE_NOTE} as its own line under the
|
|
63
|
+
heading, and end the run. Do not keep investigating without new evidence.
|
|
52
64
|
3. Fix it, and add a regression test that fails without the fix — run that test to watch it
|
|
53
65
|
fail before the fix and pass after.
|
|
54
|
-
4. Mark it fixed in BUGS.md — ${backlogMoveGuidance("BUGS.md", "## Open", "## Fixed")}
|
|
66
|
+
4. Mark it fixed in BUGS.md — ${backlogMoveGuidance("BUGS.md", "## Open", "## Fixed", "BUGS-FIXED.md")}
|
|
55
67
|
5. In the moved entry, write the required validation-gap trace line (format below).
|
|
56
68
|
6. Verify last, after the BUGS.md edits, so one run of the project's check covers everything
|
|
57
69
|
you changed (see "Leave the project working" below).
|
|
@@ -76,7 +88,7 @@ within that budget, there is nothing to do.`,
|
|
|
76
88
|
1. Check what is already waiting: the prompt's <backlog-index> block lists PLANS.md's
|
|
77
89
|
\`## Planned\` entries with each entry's line range.
|
|
78
90
|
- A plan carrying a ${NEEDS_REVIEW_NOTE} note outranks adding another plan: split it into
|
|
79
|
-
independently
|
|
91
|
+
independently mergeable sub-plans that cross-reference each other (per PLAN_SIZING below,
|
|
80
92
|
each with its own acceptance criteria), then remove the note. That split is this run's task.
|
|
81
93
|
- A plan carrying a ${NEEDS_REPLAN_NOTE} note also outranks adding another plan: read the
|
|
82
94
|
quoted objections and the code they name, then rewrite the plan so an implementation
|
|
@@ -84,18 +96,19 @@ within that budget, there is nothing to do.`,
|
|
|
84
96
|
acceptance criteria, splitting it per PLAN_SIZING, or refusing it with the objection
|
|
85
97
|
recorded when it should not be done — and remove both the note and the quoted objections.
|
|
86
98
|
- Otherwise, when PLANS.md \`## Planned\` already holds one more eligible plan than there
|
|
87
|
-
are feature instances (one waiting per instance, plus one for the next planner
|
|
99
|
+
are feature instances (one waiting per instance, plus one for the next planner run),
|
|
88
100
|
end with ${NOTHING_TO_DO} — feature has work, and a waiting plan is refined by the
|
|
89
101
|
feature run that picks it up, against the code as it stands then. Count only eligible
|
|
90
|
-
entries — those
|
|
102
|
+
entries — those the index block does not mark \`[blocked: …]\`. When it does not
|
|
91
103
|
stop, prefer a plan independent of the waiting series, so feature can run it alongside
|
|
92
104
|
the blocked ones; with more than one feature instance, an independent plan keeps every
|
|
93
105
|
runner fed.
|
|
94
|
-
2. Choose ONE unplanned feature or improvement worth doing, guided by the
|
|
106
|
+
2. Choose ONE unplanned feature or improvement worth doing, guided by the
|
|
95
107
|
project brief (TUMWATER.md when it exists with the tumwater:prompt markers, else README.md)
|
|
96
108
|
and by what already exists.
|
|
97
109
|
3. Before planning, confirm with grep that the capability does not already exist and that no
|
|
98
|
-
Planned
|
|
110
|
+
Planned entry, nor any finished plan in PLANS-DONE.md, already covers it — grep the archive
|
|
111
|
+
rather than reading it, and read only the entries whose headings look related.
|
|
99
112
|
4. Ground the plan in the code: name the actual files and functions it touches, having looked
|
|
100
113
|
at them in ranges.
|
|
101
114
|
5. Write it as a short markdown section under \`## Planned\` in PLANS.md: goal, approach, files
|
|
@@ -106,24 +119,25 @@ ${DECOMPOSITION_GUIDANCE}`,
|
|
|
106
119
|
{
|
|
107
120
|
id: "readme",
|
|
108
121
|
tier: "small",
|
|
109
|
-
title: "README
|
|
122
|
+
title: "brief and README keeper",
|
|
110
123
|
find: `Keep the project brief — TUMWATER.md when it exists with the tumwater:prompt markers, else
|
|
111
124
|
README.md — accurate against the actual state of the project.
|
|
112
125
|
1. Work from the delta, not from scratch: \`git log --oneline <last readme commit>..main\` names
|
|
113
|
-
everything that
|
|
114
|
-
trailer
|
|
126
|
+
everything that merged since your last sync — your new commits carry a \`${README_TRAILER}N\`
|
|
127
|
+
trailer and older ones \`${README_TRAILER_LEGACY}N\`; \`git log -E --grep='${README_TRAILER_GREP}' -1 --format=%H\`
|
|
128
|
+
names the last one. Read only
|
|
115
129
|
what those commits touched.
|
|
116
|
-
2. If the brief is already accurate, there is nothing to do: a
|
|
130
|
+
2. If the brief is already accurate, there is nothing to do: a merge that touched no
|
|
117
131
|
user-facing surface (commands, flags, config keys, docs) needs no sync.
|
|
118
132
|
3. The status section (between the tumwater:status markers) describes CURRENT STATE ONLY, and
|
|
119
133
|
you rewrite it wholesale on each sync — never append to it. It carries exactly two things:
|
|
120
134
|
(a) a one-line version/capability summary — no command or flag lists, which belong in the
|
|
121
135
|
usage docs, and (b) one line pointing at PLANS.md, BUGS.md, and QUESTIONS.md for open work —
|
|
122
|
-
never a copy of their entries, which every
|
|
136
|
+
never a copy of their entries, which every run already reads there.
|
|
123
137
|
4. Keep these out of the status section:
|
|
124
138
|
- Main's build and suite state: it is reported live by \`tumwater status\` (its mainCheck) —
|
|
125
|
-
never stamped into the section, so a
|
|
126
|
-
- Per-
|
|
139
|
+
never stamped into the section, so a merge needs no README commit to refresh it.
|
|
140
|
+
- Per-run merge narrative: merges are recorded by their owning roles in
|
|
127
141
|
PLANS.md/BUGS.md and git log; stale narrative found in the section is deleted as part of
|
|
128
142
|
updating it (that is an update, not a loss).
|
|
129
143
|
If the section exceeds ~1KB it has drifted back into narrative — prune it to the state-only
|
|
@@ -132,7 +146,7 @@ README.md — accurate against the actual state of the project.
|
|
|
132
146
|
only the director and steward edit.
|
|
133
147
|
Keep the brief short: a summary, the status, and brief usage; mechanics and reference detail
|
|
134
148
|
belong in separate docs it links to, so move detail there instead of growing the brief. Never
|
|
135
|
-
edit the
|
|
149
|
+
edit the brief between the tumwater:prompt markers.`,
|
|
136
150
|
},
|
|
137
151
|
{
|
|
138
152
|
id: "organize",
|
|
@@ -140,8 +154,8 @@ edit the initial prompt between the tumwater:prompt markers.`,
|
|
|
140
154
|
title: "code organizer",
|
|
141
155
|
// Written against the 2026-10-05/06 churn: with minor fixes exhausted and the shared
|
|
142
156
|
// small-and-self-contained scope rule in force, organize reorganized the whole tree one
|
|
143
|
-
// directory per tick (45 of 86
|
|
144
|
-
// stated. Major refactors stay welcome; they must be considered whole and
|
|
157
|
+
// directory per tick (45 of 86 merges in four hours) with no target structure ever
|
|
158
|
+
// stated. Major refactors stay welcome; they must be considered whole and merge whole.
|
|
145
159
|
find: `Find ONE way the code could be better organized, and restructure it.
|
|
146
160
|
1. First rank the production source files (not the tests) by \`wc -l\`. A production module
|
|
147
161
|
several times the project's median file size almost always holds more than one
|
|
@@ -176,10 +190,10 @@ organize changes where code lives and how it is divided, not what it does. Updat
|
|
|
176
190
|
imports/references so the project still builds and tests still pass. A change is complete only
|
|
177
191
|
when a grep for every old path and every moved or renamed name — over the source, the tests,
|
|
178
192
|
and the markdown docs (doc comments, PLANS.md, BUGS.md) — finds no stale reference.`,
|
|
179
|
-
scope: `- Do exactly ONE task, then stop — but unlike the other
|
|
193
|
+
scope: `- Do exactly ONE task, then stop — but unlike the other roles' tasks, yours need not be
|
|
180
194
|
small or self-contained: a restructure worth doing often takes real refactoring across many
|
|
181
|
-
files, and one coherent change
|
|
182
|
-
Where PRINCIPLES.md asks for one focused change per
|
|
195
|
+
files, and one coherent change merged whole beats the same change spread over many runs.
|
|
196
|
+
Where PRINCIPLES.md asks for one focused change per run, for this role that means one
|
|
183
197
|
coherent restructure. Complete and correct still beats big and half-done.
|
|
184
198
|
- Choose the task within your first ~15 tool calls, in a handful of turns. A restructure that
|
|
185
199
|
would need more than roughly 150 tool calls, or that you could not finish with the project
|
|
@@ -191,10 +205,14 @@ and the markdown docs (doc comments, PLANS.md, BUGS.md) — finds no stale refer
|
|
|
191
205
|
title: "test coverage improver",
|
|
192
206
|
find: `Find ONE meaningful gap in unit test coverage — an untested module, branch, or edge case
|
|
193
207
|
that could plausibly break — and close it with focused tests.
|
|
194
|
-
1.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
208
|
+
1. The team's own record of what made past bugs hard to confirm is the first evidence: run
|
|
209
|
+
\`${VALIDATION_GAP_QUERY}\` and read the entry above each hit and its free-text sentence;
|
|
210
|
+
when it names a module, branch or behavior (or the entry's fix touched one), that is the
|
|
211
|
+
first candidate — a \`no-fake\` or \`no-repro\` trace names test infrastructure to build.
|
|
212
|
+
Only when no recent trace names a candidate: Locate it from evidence rather than by reading
|
|
213
|
+
every module — compare the source module list against the test files (a module with no test
|
|
214
|
+
is the first candidate), or run the project's coverage command — for an npm project that is
|
|
215
|
+
\`npm run test:coverage\`, piped through \`tail\` — and pick the file with the most uncovered
|
|
198
216
|
lines from the deterministic-coverage table at the end of its output — node's own table above
|
|
199
217
|
it can flip between runs on the same tree, so quote the deterministic numbers.
|
|
200
218
|
2. Then read only that file and its existing tests — every test that imports it, not just the
|
|
@@ -212,17 +230,18 @@ scratch analysis scripts — that is a different, much larger task.`,
|
|
|
212
230
|
tier: "default",
|
|
213
231
|
title: "code cleaner",
|
|
214
232
|
find: `When a \`<backlog-structure>\` block is present in your prompt, that repair is instead
|
|
215
|
-
this
|
|
216
|
-
|
|
217
|
-
|
|
233
|
+
this run's ONE task: move each listed entry to the section its heading's dates say it belongs in
|
|
234
|
+
(cut and paste, under the existing \`## \` heading — never add, remove, or rename a \`## \`
|
|
235
|
+
heading), leave its text verbatim, and change nothing else. An entry listed under PLANS-DONE.md's
|
|
236
|
+
\`## Done\` with no done date goes back under PLANS.md's \`## Planned\`.
|
|
218
237
|
|
|
219
238
|
Otherwise, pick ONE kind of uncleanliness — dead code, misleading names, commented-out blocks,
|
|
220
239
|
overly clever constructs, missing or wrong doc comments on public surfaces, inconsistent
|
|
221
|
-
style, or deeply nested branching (a function whose if/
|
|
240
|
+
style, or deeply nested branching (a function whose if/for/switch nesting runs four or more
|
|
222
241
|
levels deep, or an else-if chain a reader cannot hold; flatten it with early returns, guard
|
|
223
242
|
clauses, or extracted named helpers) — and sweep every instance of that kind across the tree: grep for it over the source, the
|
|
224
|
-
tests, and the markdown docs, and fix them all in this
|
|
225
|
-
holds is one focused change, not one site per
|
|
243
|
+
tests, and the markdown docs, and fix them all in this run. One theme applied everywhere it
|
|
244
|
+
holds is one focused change, not one site per run. Do not change behavior.
|
|
226
245
|
${searchGuidance("clean")}
|
|
227
246
|
Grep is your detector:
|
|
228
247
|
- an exported name with a single hit across the tree is dead;
|
|
@@ -232,23 +251,23 @@ Grep is your detector:
|
|
|
232
251
|
file's indent width (for 2-space code \`^ {10,}(if|for|while|switch) \\(\`, for 4-space
|
|
233
252
|
Python \`^ {16,}(if|for|while) \`). Hits are candidates, not proof: an object literal or class
|
|
234
253
|
body also adds indentation, so read the function and confirm the nesting before you count it.
|
|
235
|
-
Examples of a kind: comments that still name a removed mechanism;
|
|
236
|
-
|
|
254
|
+
Examples of a kind: comments that still name a removed mechanism; comments citing a PLANS.md
|
|
255
|
+
entry title that no longer exists; doc comments citing a renamed helper.
|
|
237
256
|
Keep the diff under about 300 changed lines. When the kind has more instances than that, sweep
|
|
238
257
|
one directory or subsystem completely instead — still one kind of fix throughout — and say in
|
|
239
258
|
your WHY which instances remain.
|
|
240
|
-
Internal-only exports are caught by test/exports.test.ts in the suite, so do not spend a
|
|
259
|
+
Internal-only exports are caught by test/exports.test.ts in the suite, so do not spend a run
|
|
241
260
|
on them. A rename or deletion is complete only when a grep for the old name over the source, the
|
|
242
261
|
tests, and the markdown docs finds nothing stale; a doc comment you write or fix is a claim about
|
|
243
262
|
the code — check it against the code before you end.`,
|
|
244
263
|
},
|
|
245
264
|
{
|
|
246
|
-
id: "
|
|
265
|
+
id: "dedupe",
|
|
247
266
|
tier: "default",
|
|
248
|
-
title: "
|
|
267
|
+
title: "duplication remover",
|
|
249
268
|
find: `Find ONE instance of meaningful repetition — duplicated logic, copy-pasted blocks, or
|
|
250
269
|
parallel structures that should share a helper — and factor it out.
|
|
251
|
-
${searchGuidance("
|
|
270
|
+
${searchGuidance("dedupe")}
|
|
252
271
|
Repetition shows up in grep before it shows up in reading: search for a distinctive expression,
|
|
253
272
|
error message, or sequence of calls and see where else it recurs. Factor it out into a single
|
|
254
273
|
well-named place and update all call sites. Do not abstract things that are merely superficially
|
|
@@ -267,9 +286,9 @@ serializes what could overlap, unnecessary subprocess spawns, or unbounded growt
|
|
|
267
286
|
over time.
|
|
268
287
|
${searchGuidance("perf")}
|
|
269
288
|
Then:
|
|
270
|
-
- Hot paths are where the process actually spends time — pollers, per-
|
|
289
|
+
- Hot paths are where the process actually spends time — pollers, repeating per-run work, anything
|
|
271
290
|
called per request or per line of a growing file — so start from those entry points (grep for
|
|
272
|
-
the poll/interval/
|
|
291
|
+
the poll/interval/for-while sites), not from a file listing.
|
|
273
292
|
- Pick the ONE with the best ratio of measured benefit to risk.
|
|
274
293
|
- Before changing anything, convince yourself the cost is real (measure or reason from actual
|
|
275
294
|
data sizes — a quick timing in a scratch script is ideal).
|
|
@@ -285,46 +304,49 @@ exists, there is nothing to do.`,
|
|
|
285
304
|
find: `Act as a first-time user of this product: follow the README's usage instructions literally and check outputs against what the docs promise. You never edit source, tests, or docs — BUGS.md is your only write.
|
|
286
305
|
|
|
287
306
|
Steps:
|
|
288
|
-
1. Pick ONE flow. The README's usage section is your menu of flows; order them cheapest-first (read-only inspection before anything that launches processes) and pick ONE per
|
|
289
|
-
2. Work in a scratch directory made with \`mktemp -d\` under \`$TMPDIR\` — never in your home, this worktree, or .tumwater/. Build the product fresh per its README (your worktree resets to main every
|
|
307
|
+
1. Pick ONE flow. The README's usage section is your menu of flows; order them cheapest-first (read-only inspection before anything that launches processes) and pick ONE per run. Your prompt carries a Flow coverage block from the team's own record: exercise the flow at the top of that list unless you have a concrete reason not to, so the rotation moves through every flow instead of converging on the cheapest.
|
|
308
|
+
2. Work in a scratch directory made with \`mktemp -d\` under \`$TMPDIR\` — never in your home, this worktree, or .tumwater/. Build the product fresh per its README (your worktree resets to main every run, so there is never a stale binary), then run the built artifact against the scratch dir — CLI commands, endpoints via curl.
|
|
290
309
|
3. Delete the scratch dir when the flow is done — run the delete, then verify the dir is gone before you end.
|
|
291
|
-
4. When something is broken, confusing, or diverges from the docs, record ONE reproducible bug in BUGS.md: exact commands, expected vs actual. If the flow works as documented, there is nothing to do: a cheap flow that passes leaves NO record in the repo — declare nothing-to-do instead; a note commit every cadence would move main and wake every sleeping
|
|
310
|
+
4. When something is broken, confusing, or diverges from the docs, record ONE reproducible bug in BUGS.md: exact commands, expected vs actual. If the flow works as documented, there is nothing to do: a cheap flow that passes leaves NO record in the repo — declare nothing-to-do instead; a note commit every cadence would move main and wake every sleeping role early.
|
|
292
311
|
|
|
293
312
|
Safety rails for anything you launch:
|
|
294
|
-
- Every process gets a hard time limit and an explicit kill; no listening process may outlive your
|
|
313
|
+
- Every process gets a hard time limit and an explicit kill; no listening process may outlive your run.
|
|
295
314
|
- Servers bind ephemeral high ports, never the product's documented default port, on loopback only — check a flag that widens the bind (e.g. \`--all-interfaces\`) from its startup banner and stop it at once.
|
|
296
315
|
- Track each background process by its own pid (in \`cd dir && server & echo $!\`, \`$!\` names the subshell, not the server — \`cd\` first).
|
|
297
|
-
- When a flow starts long-running or model-backed processes, prefer a deterministic offline mode (a fake/shim) if the project documents one; otherwise do ONE real bounded run — constrain it to minimal scope (
|
|
298
|
-
- Use that expensive real mode only when the newest Verified note for the flow is older than a day; after a successful real run append one line under a ## Verified section at the end of BUGS.md (e.g. "- 2026-08-28 run (real): init + one
|
|
316
|
+
- When a flow starts long-running or model-backed processes, prefer a deterministic offline mode (a fake/shim) if the project documents one; otherwise do ONE real bounded run — constrain it to minimal scope (a minimal setup: exactly one enabled role and maxConcurrent 1), wall-cap it (~10 min including prefill), background it, and kill its whole process tree when done.
|
|
317
|
+
- Use that expensive real mode only when the newest Verified note for the flow is older than a day; after a successful real run append one line under a ## Verified section at the end of BUGS.md (e.g. "- 2026-08-28 run (real): init + one run merged; status/logs confirm").
|
|
299
318
|
|
|
300
|
-
The FLOW line — required on every
|
|
319
|
+
The FLOW line — required on every run: your final reply carries one result-carrying line — \`FLOW: <name> — <passed|bug>\` — naming the flow you exercised and whether it passed or filed a bug (spell the name as the coverage block does, e.g. \`FLOW: run (real) — passed\`), placed just before your ending (the nothing-to-do line, or the SUMMARY block when you filed a bug). The verdict is required: a bare \`FLOW: <name>\` with no \`passed|bug\` suffix is not a result and is not recorded, so the rotation never advances. tumwater records it for the next run's coverage block. A passing flow's reply ends with two lines in this form, with the name of the flow you actually exercised in place of <name>:
|
|
301
320
|
FLOW: <name> — passed
|
|
302
321
|
${NOTHING_TO_DO}`,
|
|
303
322
|
},
|
|
304
323
|
{
|
|
305
|
-
id: "
|
|
324
|
+
id: "selfcheck",
|
|
306
325
|
tier: "default",
|
|
307
|
-
title: "
|
|
308
|
-
find: `File ONE bug in BUGS.md's ## Open section per
|
|
309
|
-
<failure-digest> block in your prompt: a deterministic digest of this
|
|
326
|
+
title: "self-check: files tumwater bugs from its own failure log",
|
|
327
|
+
find: `File ONE bug in BUGS.md's ## Open section per run, or declare nothing-to-do, from the
|
|
328
|
+
<failure-digest> block in your prompt: a deterministic digest of this project's own event log over
|
|
310
329
|
the last day (per-role outcome counts, each role's time and spend by outcome, normalized error and
|
|
311
|
-
warning clusters, review rejections, and what
|
|
312
|
-
looking for the event log or per-role transcripts yourself;
|
|
330
|
+
warning clusters, review rejections, and what merged). It is your entire evidence base — do not go
|
|
331
|
+
looking for the event log or per-role transcripts yourself; tumwater injects the digest because
|
|
313
332
|
the live log lives outside your worktree.
|
|
314
|
-
1. A cluster is a bug ONLY when
|
|
315
|
-
alarm, drove the wrong state or
|
|
316
|
-
the
|
|
333
|
+
1. A cluster is a bug ONLY when tumwater's RESPONSE to it is wrong — a failure that raised no
|
|
334
|
+
alarm, drove the wrong state or sleep ladder, latched a stale verdict, or hid itself from
|
|
335
|
+
the user. A mere infrastructure failure (the model server was slow, pi exited non-zero)
|
|
317
336
|
is weather, not a bug: filing it produces an entry no bugfix run can act on.
|
|
318
|
-
2. Read the digest for that wrong response — 44 identical errors that raised no warning, a
|
|
337
|
+
2. Read the digest for that wrong response — 44 identical errors that raised no warning, a run
|
|
319
338
|
that failed in 200 ms then climbed the idle ladder, a cluster that begins on the date a
|
|
320
|
-
specific commit
|
|
321
|
-
3. Rank what you would file by LOSS, not by
|
|
339
|
+
specific commit merged.
|
|
340
|
+
3. Rank what you would file by LOSS, not by run count: the digest's time-and-spend table and
|
|
322
341
|
top loss causes price each cause in agent-hours and dollars, and a cluster that burned hours
|
|
323
342
|
outranks one that burned seconds — cite its cost when it is the reason you file.
|
|
324
|
-
4. Before filing, check BUGS.md's ## Open section and \`git log
|
|
325
|
-
for an entry that already names this cluster — no duplicate filings.
|
|
343
|
+
4. Before filing, check BUGS.md's ## Open section and \`git log ${roleCommitGrep("selfcheck")}\`
|
|
344
|
+
for an entry that already names this cluster — no duplicate filings. When that Open entry
|
|
345
|
+
carries a ${WAITING_FOR_FAILURE_PREFIX}…** note and the cluster failed again after the
|
|
346
|
+
note's date, add the new occurrence under the entry (time, merged commit, failure message)
|
|
347
|
+
and delete the note line, instead of filing a duplicate.
|
|
326
348
|
5. File it: cite the cluster's normalized key plus the correlated \`merged\` commit in the
|
|
327
|
-
entry, so the bugfix
|
|
349
|
+
entry, so the bugfix role can reproduce it.
|
|
328
350
|
BUGS.md is your only write; never edit source, tests, or docs. If every cluster is ordinary
|
|
329
351
|
infrastructure weather or already filed, there is nothing to do.`,
|
|
330
352
|
},
|
|
@@ -355,7 +377,7 @@ Then:
|
|
|
355
377
|
- Grep for those sinks in this project's own language and pick ONE hit. Trace it back to its
|
|
356
378
|
source: it is real only when you can name the input an attacker controls, the path it
|
|
357
379
|
travels, and the missing check. Read every caller on that path — a guard upstream already
|
|
358
|
-
closes it — and a sink fed only by constants or the
|
|
380
|
+
closes it — and a sink fed only by constants or the user's own trusted config is not a
|
|
359
381
|
finding.
|
|
360
382
|
- Prove it with a test that feeds the hostile input (a \`../\` path, a shell metacharacter, an
|
|
361
383
|
oversized body, a foreign Origin) and fails before your fix. Then fix it at the boundary —
|
|
@@ -389,14 +411,14 @@ concurrent processes or tasks — for these failure modes:
|
|
|
389
411
|
rejection handler) where the caller needs to know;
|
|
390
412
|
- cleanup skipped on the error path: a leaked lock file, child process, file handle, listener,
|
|
391
413
|
or temp directory;
|
|
392
|
-
- a retry with no bound or
|
|
414
|
+
- a retry with no bound or sleep, or a queue, cache, log, or map that only ever grows;
|
|
393
415
|
- a read-modify-write that two processes or tasks can interleave, losing one update.
|
|
394
416
|
${searchGuidance("robustness")}
|
|
395
417
|
Then:
|
|
396
418
|
- Grep for those patterns in this project's own language and pick ONE hit on a path that
|
|
397
419
|
actually runs. Read its callers: it is real only when you can name the concrete fault (the
|
|
398
420
|
process is killed during this write, this file is empty after a crash, this child never
|
|
399
|
-
exits) and the wrong outcome it causes (lost state, a stuck
|
|
421
|
+
exits) and the wrong outcome it causes (lost state, a stuck role, a crash, a silently wrong
|
|
400
422
|
answer).
|
|
401
423
|
- Prove it with a test that injects that fault — a truncated file, a fake that throws or
|
|
402
424
|
hangs, a timer that never fires — and fails before your fix; then make the code handle it
|
|
@@ -423,75 +445,31 @@ arguments, config files, environment), and rough edges you meet while running th
|
|
|
423
445
|
{
|
|
424
446
|
id: "steward",
|
|
425
447
|
tier: "default",
|
|
426
|
-
title: "
|
|
448
|
+
title: "backlog curator",
|
|
427
449
|
find: `Make ONE curation move on this project's records — the most valuable one.
|
|
428
|
-
1. Re-read the
|
|
450
|
+
1. Re-read the brief, PRINCIPLES.md, PLANS.md, BUGS.md — and QUESTIONS.md if it
|
|
429
451
|
exists — and skim the codebase's shape (sizes, module list, test count).
|
|
430
452
|
2. Then make ONE curation move, the most valuable one:
|
|
431
|
-
- delete or merge stale/duplicative/superseded PLANS.md entries
|
|
432
|
-
|
|
433
|
-
|
|
453
|
+
- delete or merge stale/duplicative/superseded PLANS.md entries: move each one under
|
|
454
|
+
PLANS.md's ## Done with a one-line epitaph as its body (tumwater archives it to
|
|
455
|
+
PLANS-DONE.md when your change commits), keeping the entry's title, because
|
|
456
|
+
\`plans-citations.test.ts\` fails when a \`PLANS.md "<title>"\` citation in a \`src/\` or
|
|
457
|
+
\`test/\` comment matches no heading;
|
|
458
|
+
- flag drift between what is being built and the brief as a PLANS.md note;
|
|
434
459
|
- tighten or update a principle or complexity budget in PRINCIPLES.md;
|
|
435
460
|
- record a structural risk in BUGS.md;
|
|
436
|
-
- promote a recurring non-\`none\` \`gap:\` tag — three or more
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
- compress an overflowing ## Done or ## Fixed section (rules below).
|
|
461
|
+
- promote a recurring non-\`none\` \`gap:\` tag — three or more Fixed entries carrying it —
|
|
462
|
+
into a PLANS.md entry for the infrastructure that would retire it, citing those entries.
|
|
463
|
+
${VALIDATION_GAP_TALLY}
|
|
440
464
|
You edit only markdown — never source.
|
|
441
465
|
|
|
442
|
-
Reading the backlog files:
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
needs
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
\`**Validation gap:**\` line in its body: read that one line (\`grep -n 'Validation gap' FILE\`), not
|
|
449
|
-
the whole body.
|
|
466
|
+
Reading the backlog files: PLANS.md and BUGS.md hold open work, so read them whole when your move
|
|
467
|
+
needs it. Finished entries live in PLANS-DONE.md and BUGS-FIXED.md, newest first, and those files
|
|
468
|
+
only grow: never read them whole. Search them with \`grep -n\`, and read an entry by its line range
|
|
469
|
+
only where your move needs its body. The prompt's <backlog-index> block lists the newest ones.
|
|
470
|
+
Finished history is not curated: nothing reads the archive files whole, so they are never
|
|
471
|
+
compressed or trimmed.
|
|
450
472
|
|
|
451
|
-
|
|
452
|
-
- Keep the ten most recent entries verbatim (newest first, by position in file) and compress
|
|
453
|
-
older ones to one line each:
|
|
454
|
-
\`- <title> (planned YYYY-MM-DD, done YYYY-MM-DD; commit(s) <sha>[, <sha>])\` — title and
|
|
455
|
-
dates from the entry's heading.
|
|
456
|
-
- The hashes are the LANDING commit(s): an explicit landing citation in the entry body (the
|
|
457
|
-
"tick N (\`<sha>\`)" form naming the commit that landed it), else git log on main, whose
|
|
458
|
-
self-explaining subjects name the role and describe the change.
|
|
459
|
-
- Never use a verification or base reference ("Verified … against main \`<sha>\`", "at HEAD
|
|
460
|
-
\`<sha>\`") as the record's hash — bodies citing several shas need the one cited as having
|
|
461
|
-
landed the work — and when no landing commit exists (a plan closed without code change says
|
|
462
|
-
so in its Done note) omit the commit(s) field rather than guess.
|
|
463
|
-
- The one-line form keeps every existing cross-reference resolvable: references cite titles or
|
|
464
|
-
commit hashes, both preserved.
|
|
465
|
-
|
|
466
|
-
Compressing BUGS.md ## Fixed — BUGS.md's ## Fixed section is curated to stay bounded by the same
|
|
467
|
-
policy:
|
|
468
|
-
- Keep the ten most recent entries verbatim (newest first) and compress older ones to one line
|
|
469
|
-
each: \`- <symptom headline> (<the heading's own date clause>; commit <sha>; gap: <tag>)\` —
|
|
470
|
-
carrying the entry's validation-gap tag as a suffix, and omitting the \`gap: <tag>\` suffix
|
|
471
|
-
entirely when the tag is \`none\` (so the common case costs nothing).
|
|
472
|
-
- The headline comes from the entry's heading, and the date clause is copied from that heading
|
|
473
|
-
as-is: BUGS.md headings vary across found/reported/re-recorded × fixed/closed/resolved and
|
|
474
|
-
may carry extra notes inside their parentheses, so do not normalize or fabricate dates; when
|
|
475
|
-
a heading carries no dates at all, omit that part of the line.
|
|
476
|
-
- The commit is the entry's LANDING commit — the one that merged the fix to main: an explicit
|
|
477
|
-
landing citation in the entry body (the "tick N (\`<sha>\`)" form naming the fix commit
|
|
478
|
-
itself), else git log on main, whose self-explaining subjects name the role and describe the
|
|
479
|
-
change; never use a verification reference ("Verified … on main \`<sha>\`", "at HEAD
|
|
480
|
-
\`<sha>\`") as the record's hash — bodies citing several shas need the one cited as having
|
|
481
|
-
landed the fix.
|
|
482
|
-
- When no landing commit exists (an entry closed without code change says so in its
|
|
483
|
-
**Resolution:** note) omit the \`commit\` field rather than guess, keeping the \`gap: <tag>\`
|
|
484
|
-
suffix (the no-commit variant reads \`- <symptom headline> (<date clause>; gap: <tag>)\`, and
|
|
485
|
-
plain \`(<date clause>)\` when the tag is \`none\`).
|
|
486
|
-
${VALIDATION_GAP_GUIDANCE}
|
|
487
|
-
|
|
488
|
-
Rules for both compressions:
|
|
489
|
-
- Never compress an entry carrying a standing **Refused …** note — the objection stands until
|
|
490
|
-
a human or director edits it, and compression would bury it; such entries stay full (they are
|
|
491
|
-
rare).
|
|
492
|
-
- Compression is lossy on purpose: pre-compression text stays in git history — no archive file.
|
|
493
|
-
- One curation move per tick still holds: one steward tick compresses one section's overflow
|
|
494
|
-
(or makes any other planned move) — a large backlog takes several ticks to reach the window,
|
|
495
|
-
each shrinking the file by tens of KB; once at the window it stays bounded.`,
|
|
473
|
+
${VALIDATION_GAP_GUIDANCE}`,
|
|
496
474
|
},
|
|
497
475
|
];
|