@moretea-labs/forge 1.7.0 → 1.7.2
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/AGENTS.md +2 -0
- package/CHANGELOG.md +26 -0
- package/CLAUDE.md +2 -0
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/agents/openai.yaml +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +2 -0
- package/assets/plugin-registry.v1.json +3 -3
- package/assets/skill-version.json +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +17 -0
- package/assets/templates/helpers/inspect-project-state.ts +8 -6
- package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
- package/assets/templates/helpers/workflow-contract.ts +5 -1
- package/docs/architecture/CURRENT.md +12 -4
- package/docs/forge-plugin-management.md +1 -1
- package/docs/operations/controller-performance-and-502.md +19 -0
- package/docs/operations/homebrew.md +2 -2
- package/package.json +5 -2
- package/scripts/architecture-event.ts +2 -820
- package/scripts/architecture-queue.sh +2 -645
- package/scripts/archive-architecture-request.sh +2 -242
- package/scripts/archive-workflow.sh +1 -291
- package/scripts/benchmark-work-efficiency.ts +0 -0
- package/scripts/capability-config.ts +2 -392
- package/scripts/capability-resolver.ts +2 -503
- package/scripts/capture-plan.sh +1 -332
- package/scripts/check-agent-tooling.sh +2 -1531
- package/scripts/check-architecture-sync.sh +2 -302
- package/scripts/check-brain-manifest.sh +2 -253
- package/scripts/check-context-files.sh +2 -47
- package/scripts/check-deploy-sql-order.sh +2 -115
- package/scripts/check-runtime-architecture.mjs +243 -16
- package/scripts/check-skill-version.ts +3 -191
- package/scripts/check-source-duplication.mjs +61 -0
- package/scripts/check-stable-baseline.ts +0 -0
- package/scripts/check-task-sync.sh +2 -63
- package/scripts/check-task-workflow.sh +2 -1000
- package/scripts/codex-handoff-resume.sh +2 -267
- package/scripts/context-contract-sync.sh +2 -514
- package/scripts/contract-run.ts +2 -463
- package/scripts/contract-worktree.sh +1 -702
- package/scripts/ensure-task-workflow.sh +1 -1192
- package/scripts/inspect-project-state.ts +4 -279
- package/scripts/lib/project-init-lib.sh +7 -2
- package/scripts/lib/run-forge-helper.sh +19 -0
- package/scripts/lib/run-forge-helper.ts +26 -0
- package/scripts/migrate-project-template.sh +1 -33
- package/scripts/migrate-workflow-docs.ts +4 -412
- package/scripts/new-plan.sh +1 -180
- package/scripts/new-spec.sh +1 -47
- package/scripts/new-sprint.sh +1 -46
- package/scripts/plan-to-todo.sh +1 -771
- package/scripts/prepare-codex-handoff.sh +2 -201
- package/scripts/prepare-handoff.sh +1 -78
- package/scripts/refresh-current-status.sh +2 -467
- package/scripts/run-governed-gate.ts +3 -0
- package/scripts/select-agent-context-blocks.sh +2 -64
- package/scripts/ship-worktrees.sh +1 -531
- package/scripts/sprint-backlog.sh +1 -834
- package/scripts/stage-runtime-release.ts +2 -1
- package/scripts/summarize-failures.sh +2 -123
- package/scripts/switch-plan.sh +1 -150
- package/scripts/sync-brain-docs.sh +2 -379
- package/scripts/sync-generated-authority.mjs +175 -0
- package/scripts/verify-contract.sh +2 -593
- package/scripts/verify-sprint.sh +1 -500
- package/scripts/workflow-contract.ts +4 -201
- package/scripts/workstream-sync.sh +2 -261
- package/src/cli/agent-jobs/executor-health.ts +1 -1
- package/src/cli/commands/plugin.ts +12 -3
- package/src/cli/controller/check-runner.ts +7 -2
- package/src/cli/controller/context-pack.ts +46 -21
- package/src/cli/github/contracts.ts +16 -0
- package/src/cli/github/github.ts +2 -16
- package/src/cli/github/session.ts +2 -1
- package/src/cli/local-bridge/facade-api.ts +37 -47
- package/src/cli/local-bridge/server.ts +2 -2
- package/src/cli/mcp/legacy-tool-service.ts +10 -33
- package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
- package/src/cli/mcp/repository-tools.ts +125 -101
- package/src/cli/mcp/server.ts +57 -13
- package/src/cli/mcp/tool-contract.ts +14 -0
- package/src/cli/mcp/toolset.ts +2 -2
- package/src/cli/mcp/transports/http.ts +23 -0
- package/src/cli/repositories/command-classifier.ts +2 -2
- package/src/cli/repositories/command-executor.ts +24 -6
- package/src/cli/repositories/repository-snapshot.ts +5 -2
- package/src/cli/repositories/structured-git.ts +57 -3
- package/src/cli/repository/inspector.ts +11 -3
- package/src/runtime/context/generic-lsp-provider.ts +1 -1
- package/src/runtime/context/semantic-navigation-contract.ts +61 -0
- package/src/runtime/context/semantic-navigation.ts +9 -61
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +69 -29
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
- package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
- package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
- package/src/runtime/control-plane/execution/work-handle-authority.ts +150 -0
- package/src/runtime/control-plane/execution/work-handle-store.ts +1 -1
- package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
- package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
- package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
- package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
- package/src/runtime/control-plane/execution/work-task-receipt.ts +4 -43
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +13 -3
- package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
- package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
- package/src/runtime/control-plane/facade/controller-round-relay.ts +164 -37
- package/src/runtime/control-plane/facade/controller-session-store.ts +183 -24
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +15 -1
- package/src/runtime/control-plane/facade/goal-workloop.ts +329 -148
- package/src/runtime/control-plane/facade/index.ts +2 -0
- package/src/runtime/control-plane/facade/plan-contract-store.ts +90 -22
- package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
- package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
- package/src/runtime/control-plane/facade/types.ts +68 -5
- package/src/runtime/control-plane/facade/work-contract-store.ts +3 -209
- package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +14 -7
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +5 -1
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +13 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +15 -6
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +54 -5
- package/src/runtime/control-plane/launcher/thin-launcher.ts +56 -7
- package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
- package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
- package/src/runtime/control-plane/routing/route-policy.ts +18 -6
- package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
- package/src/runtime/evidence/process-check-execution.ts +18 -0
- package/src/runtime/execution/jobs/child-reference.ts +6 -2
- package/src/runtime/execution/process-runtime/check-result.ts +53 -18
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
- package/src/runtime/execution/process-runtime/command-facade.ts +39 -17
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +20 -3
- package/src/runtime/execution/process-runtime/persisted-check.ts +4 -1
- package/src/runtime/execution/process-runtime/runtime.ts +10 -0
- package/src/runtime/execution/process-runtime/types.ts +2 -12
- package/src/runtime/execution/work-activity.ts +21 -0
- package/src/runtime/execution/workers/executor.ts +18 -13
- package/src/runtime/gateway/mcp/execution-tools.ts +35 -2930
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
- package/src/runtime/gateway/mcp/router.ts +2 -2
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +21 -2
- package/src/runtime/gateway/mcp/runtime-tools.ts +815 -1015
- package/src/runtime/plugins/app-store-connect-adapter.ts +93 -28
- package/src/runtime/plugins/browser-adapter.ts +256 -1083
- package/src/runtime/plugins/browser-handoff-host.ts +2 -25
- package/src/runtime/plugins/browser-handoff.ts +18 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +121 -16
- package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
- package/src/runtime/plugins/browser-native-session-service.ts +222 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +2 -0
- package/src/runtime/plugins/browser-runtime.ts +10 -0
- package/src/runtime/plugins/browser-session-store.ts +121 -0
- package/src/runtime/plugins/browser-session-types.ts +98 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +4 -4
- package/src/runtime/plugins/external-adapter.ts +92 -58
- package/src/runtime/plugins/macos-capability-broker.ts +0 -8
- package/src/runtime/plugins/store.ts +66 -9
- package/src/runtime/plugins/types.ts +3 -1
- package/src/runtime/recovery/maintenance-executor.ts +61 -25
- package/src/runtime/root/package-connector-service.ts +46 -4
- package/src/runtime/root/package-runtime-release.ts +3 -2
- package/src/runtime/root/package-runtime-service.ts +48 -3
- package/src/runtime/root/release-manifest.ts +137 -16
- package/src/runtime/root/release-materialize.ts +109 -35
- package/src/runtime/root/types.ts +10 -0
- package/src/runtime/standalone-recovery/core.ts +425 -194
- package/src/runtime/standalone-recovery/entry.ts +1 -1
- package/src/runtime/standalone-recovery/installer.ts +1 -1
- package/src/runtime/workflow/schedules/engine.ts +113 -87
- package/src/runtime/workflow/schedules/settlement.ts +26 -23
- package/src/runtime/workflow/schedules/store.ts +79 -10
package/scripts/plan-to-todo.sh
CHANGED
|
@@ -1,774 +1,4 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
set -euo pipefail
|
|
3
|
-
|
|
4
3
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
-
|
|
6
|
-
cd "$REPO_ROOT"
|
|
7
|
-
elif [[ "$SCRIPT_DIR" == */.ai/harness/scripts ]]; then
|
|
8
|
-
cd "$SCRIPT_DIR/../../.."
|
|
9
|
-
else
|
|
10
|
-
cd "$SCRIPT_DIR/.."
|
|
11
|
-
fi
|
|
12
|
-
|
|
13
|
-
usage() {
|
|
14
|
-
cat <<'USAGE_EOF'
|
|
15
|
-
Usage: scripts/plan-to-todo.sh --plan <plan-file>
|
|
16
|
-
USAGE_EOF
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
# Source shared workflow-state library if available (installed via migration).
|
|
20
|
-
# This avoids duplicating task-state JSON generation logic.
|
|
21
|
-
_WF_LIB=".ai/hooks/lib/workflow-state.sh"
|
|
22
|
-
if [[ -f "$_WF_LIB" ]]; then
|
|
23
|
-
# shellcheck source=/dev/null
|
|
24
|
-
. "$_WF_LIB"
|
|
25
|
-
_HAS_WF_LIB=1
|
|
26
|
-
else
|
|
27
|
-
_HAS_WF_LIB=0
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
# Fallback json_escape only when workflow-state.sh is not available
|
|
31
|
-
if [[ "$_HAS_WF_LIB" -eq 0 ]]; then
|
|
32
|
-
workflow_json_escape() {
|
|
33
|
-
local value="$1"
|
|
34
|
-
value="${value//\\/\\\\}"
|
|
35
|
-
value="${value//\"/\\\"}"
|
|
36
|
-
value="${value//$'\n'/\\n}"
|
|
37
|
-
value="${value//$'\r'/\\r}"
|
|
38
|
-
value="${value//$'\t'/\\t}"
|
|
39
|
-
printf '%s' "$value"
|
|
40
|
-
}
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
extract_status() {
|
|
44
|
-
local file="$1"
|
|
45
|
-
awk '/\*\*Status\*\*:/ {sub(/^.*\*\*Status\*\*: */, ""); gsub(/\r/, ""); print; exit}' "$file" | xargs
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
plan_evidence_contract_error() {
|
|
49
|
-
local file="$1"
|
|
50
|
-
local section=""
|
|
51
|
-
local missing=0
|
|
52
|
-
|
|
53
|
-
section="$(awk '
|
|
54
|
-
BEGIN { in_section = 0 }
|
|
55
|
-
/^## Evidence Contract[[:space:]]*$/ { in_section = 1; next }
|
|
56
|
-
in_section && /^## / { exit }
|
|
57
|
-
in_section { print }
|
|
58
|
-
' "$file")"
|
|
59
|
-
|
|
60
|
-
if [[ -z "$(printf '%s' "$section" | tr -d '[:space:]')" ]]; then
|
|
61
|
-
echo "missing ## Evidence Contract section"
|
|
62
|
-
return 1
|
|
63
|
-
fi
|
|
64
|
-
|
|
65
|
-
local label line value
|
|
66
|
-
for label in "State/progress path" "Verification evidence" "Impact review|Evaluator rubric" "Stop condition" "Rollback surface"; do
|
|
67
|
-
line="$(printf '%s\n' "$section" | grep -Ei "^[[:space:]]*-[[:space:]]*(\\*\\*)?${label}(\\*\\*)?[[:space:]]*:" | head -1 || true)"
|
|
68
|
-
if [[ -z "$line" ]]; then
|
|
69
|
-
echo "missing field: ${label}"
|
|
70
|
-
missing=1
|
|
71
|
-
continue
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
value="${line#*:}"
|
|
75
|
-
value="$(printf '%s' "$value" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')"
|
|
76
|
-
if [[ -z "$value" ]] || printf '%s' "$value" | grep -Eiq '^(tbd|todo|n/a|none|unknown|\.\.\.)$'; then
|
|
77
|
-
echo "field has no concrete value: ${label}"
|
|
78
|
-
missing=1
|
|
79
|
-
fi
|
|
80
|
-
done
|
|
81
|
-
|
|
82
|
-
[[ "$missing" -eq 0 ]]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
extract_capability_id() {
|
|
86
|
-
local file="$1"
|
|
87
|
-
awk -F': ' '/^\> \*\*Capability ID\*\*:/ {print $2; exit}' "$file" | xargs
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
get_todo_source_plan() {
|
|
91
|
-
awk -F': ' '/^\> \*\*Source Plan\*\*:/ {print $2; exit}' tasks/todos.md 2>/dev/null | xargs
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
plan_slug_from_path() {
|
|
95
|
-
local plan_file="$1"
|
|
96
|
-
local base slug
|
|
97
|
-
base="$(basename "$plan_file")"
|
|
98
|
-
slug="$(printf '%s' "$base" | sed -E 's/^plan-[0-9]{8}-[0-9]{4}-//; s/\.md$//')"
|
|
99
|
-
printf '%s' "$slug"
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
plan_original_artifact_stem_from_path() {
|
|
103
|
-
local plan_file="$1"
|
|
104
|
-
local base stem
|
|
105
|
-
base="$(basename "$plan_file")"
|
|
106
|
-
stem="$(printf '%s' "$base" | sed -E 's/^plan-//; s/\.md$//')"
|
|
107
|
-
if [[ "$stem" =~ ^[0-9]{8}-[0-9]{4}-.+ ]]; then
|
|
108
|
-
printf '%s' "$stem"
|
|
109
|
-
else
|
|
110
|
-
plan_slug_from_path "$plan_file"
|
|
111
|
-
fi
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
is_transient_plan_slug() {
|
|
115
|
-
case "$1" in
|
|
116
|
-
think-plan-[0-9]*|codex-plan-[0-9]*|approved-plan-[0-9]*)
|
|
117
|
-
return 0
|
|
118
|
-
;;
|
|
119
|
-
esac
|
|
120
|
-
return 1
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
plan_title_slug_from_file() {
|
|
124
|
-
local plan_file="$1"
|
|
125
|
-
local title slug
|
|
126
|
-
[[ -f "$plan_file" ]] || return 1
|
|
127
|
-
title="$(awk '
|
|
128
|
-
/^# Plan:[[:space:]]*/ {
|
|
129
|
-
sub(/^# Plan:[[:space:]]*/, "")
|
|
130
|
-
print
|
|
131
|
-
exit
|
|
132
|
-
}
|
|
133
|
-
' "$plan_file" | xargs)"
|
|
134
|
-
[[ -n "$title" ]] || return 1
|
|
135
|
-
slug="$(printf '%s' "$title" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-{2,}/-/g')"
|
|
136
|
-
[[ -n "$slug" ]] || return 1
|
|
137
|
-
printf '%s' "$slug"
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
plan_task_profile_from_file() {
|
|
141
|
-
local plan_file="$1"
|
|
142
|
-
local profile
|
|
143
|
-
profile="$(awk '
|
|
144
|
-
/^> \*\*Task Profile\*\*:/ {
|
|
145
|
-
sub(/^> \*\*Task Profile\*\*:[[:space:]]*/, "")
|
|
146
|
-
gsub(/\r/, "")
|
|
147
|
-
print
|
|
148
|
-
exit
|
|
149
|
-
}
|
|
150
|
-
' "$plan_file" | xargs)"
|
|
151
|
-
printf '%s' "${profile:-code-change}"
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
plan_artifact_stem_from_path() {
|
|
155
|
-
local plan_file="$1"
|
|
156
|
-
local stem stamp slug title_slug
|
|
157
|
-
stem="$(plan_original_artifact_stem_from_path "$plan_file")"
|
|
158
|
-
if [[ "$stem" =~ ^[0-9]{8}-[0-9]{4}-.+ ]]; then
|
|
159
|
-
stamp="$(printf '%s' "$stem" | sed -E 's/^([0-9]{8}-[0-9]{4})-.+$/\1/')"
|
|
160
|
-
slug="$(printf '%s' "$stem" | sed -E 's/^[0-9]{8}-[0-9]{4}-//')"
|
|
161
|
-
if is_transient_plan_slug "$slug"; then
|
|
162
|
-
title_slug="$(plan_title_slug_from_file "$plan_file" || true)"
|
|
163
|
-
if [[ -n "$title_slug" && "$title_slug" != "$slug" ]]; then
|
|
164
|
-
printf '%s-%s' "$stamp" "$title_slug"
|
|
165
|
-
return 0
|
|
166
|
-
fi
|
|
167
|
-
fi
|
|
168
|
-
printf '%s' "$stem"
|
|
169
|
-
else
|
|
170
|
-
plan_slug_from_path "$plan_file"
|
|
171
|
-
fi
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
policy_get() {
|
|
175
|
-
local jq_path="$1"
|
|
176
|
-
local default_value="${2:-}"
|
|
177
|
-
local value=""
|
|
178
|
-
|
|
179
|
-
if [[ -f ".ai/harness/policy.json" ]] && command -v jq >/dev/null 2>&1; then
|
|
180
|
-
value="$(jq -r "$jq_path // empty" ".ai/harness/policy.json" 2>/dev/null || true)"
|
|
181
|
-
if [[ -n "$value" ]]; then
|
|
182
|
-
printf '%s' "$value"
|
|
183
|
-
return 0
|
|
184
|
-
fi
|
|
185
|
-
fi
|
|
186
|
-
|
|
187
|
-
printf '%s' "$default_value"
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
is_linked_worktree() {
|
|
191
|
-
local git_dir
|
|
192
|
-
git_dir="$(git rev-parse --git-dir 2>/dev/null || true)"
|
|
193
|
-
[[ "$git_dir" == *".git/worktrees/"* ]]
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
plan_requests_contract_worktree() {
|
|
197
|
-
local file="$1"
|
|
198
|
-
local auto_for_contract_tasks
|
|
199
|
-
|
|
200
|
-
if grep -Eiq '^\> \*\*(Contract Level|Execution Mode|Execution Surface)\*\*:[[:space:]]*(false|primary|inline)[[:space:]]*$' "$file"; then
|
|
201
|
-
return 1
|
|
202
|
-
fi
|
|
203
|
-
|
|
204
|
-
if grep -Eiq '^\> \*\*(Contract Level|Execution Mode|Execution Surface)\*\*:[[:space:]]*(true|worktree|contract-worktree)[[:space:]]*$' "$file"; then
|
|
205
|
-
return 0
|
|
206
|
-
fi
|
|
207
|
-
|
|
208
|
-
auto_for_contract_tasks="$(policy_get '.worktree_strategy.auto_for_contract_tasks' 'false')"
|
|
209
|
-
[[ "$auto_for_contract_tasks" == "true" ]]
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
maybe_start_contract_worktree() {
|
|
213
|
-
local file="$1"
|
|
214
|
-
|
|
215
|
-
[[ "${FORGE_CONTRACT_WORKTREE:-}" != "1" ]] || return 0
|
|
216
|
-
[[ "${FORGE_DISABLE_CONTRACT_WORKTREE:-}" != "1" ]] || return 0
|
|
217
|
-
[[ -x "scripts/contract-worktree.sh" ]] || return 0
|
|
218
|
-
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
|
|
219
|
-
! is_linked_worktree || return 0
|
|
220
|
-
plan_requests_contract_worktree "$file" || return 0
|
|
221
|
-
|
|
222
|
-
bash "scripts/contract-worktree.sh" start --plan "$file"
|
|
223
|
-
exit $?
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
set_plan_status() {
|
|
227
|
-
local file="$1"
|
|
228
|
-
local status="$2"
|
|
229
|
-
local tmp_file
|
|
230
|
-
tmp_file="$(mktemp)"
|
|
231
|
-
awk -v next_status="$status" '
|
|
232
|
-
BEGIN { updated = 0 }
|
|
233
|
-
{
|
|
234
|
-
if (!updated && $0 ~ /\*\*Status\*\*:/) {
|
|
235
|
-
sub(/\*\*Status\*\*: .*/, "**Status**: " next_status)
|
|
236
|
-
updated = 1
|
|
237
|
-
}
|
|
238
|
-
print
|
|
239
|
-
}
|
|
240
|
-
' "$file" > "$tmp_file"
|
|
241
|
-
mv "$tmp_file" "$file"
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
unique_archive_path() {
|
|
245
|
-
local desired="$1"
|
|
246
|
-
if [[ ! -e "$desired" ]]; then
|
|
247
|
-
printf '%s' "$desired"
|
|
248
|
-
return
|
|
249
|
-
fi
|
|
250
|
-
|
|
251
|
-
local stem counter candidate
|
|
252
|
-
stem="${desired%.md}"
|
|
253
|
-
counter=2
|
|
254
|
-
candidate="${stem}-v${counter}.md"
|
|
255
|
-
while [[ -e "$candidate" ]]; do
|
|
256
|
-
counter=$((counter + 1))
|
|
257
|
-
candidate="${stem}-v${counter}.md"
|
|
258
|
-
done
|
|
259
|
-
printf '%s' "$candidate"
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
rewrite_plan_artifact_references() {
|
|
263
|
-
local plan_file="$1"
|
|
264
|
-
local from_stem="$2"
|
|
265
|
-
local to_stem="$3"
|
|
266
|
-
local tmp_file
|
|
267
|
-
|
|
268
|
-
[[ -n "$from_stem" && -n "$to_stem" && "$from_stem" != "$to_stem" ]] || return 0
|
|
269
|
-
|
|
270
|
-
tmp_file="$(mktemp)"
|
|
271
|
-
sed \
|
|
272
|
-
-e "s|tasks/contracts/${from_stem}\\.contract\\.md|tasks/contracts/${to_stem}.contract.md|g" \
|
|
273
|
-
-e "s|tasks/reviews/${from_stem}\\.review\\.md|tasks/reviews/${to_stem}.review.md|g" \
|
|
274
|
-
-e "s|tasks/notes/${from_stem}\\.notes\\.md|tasks/notes/${to_stem}.notes.md|g" \
|
|
275
|
-
"$plan_file" > "$tmp_file"
|
|
276
|
-
mv "$tmp_file" "$plan_file"
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
render_contract_file() {
|
|
280
|
-
local plan_file="$1"
|
|
281
|
-
local contract_file="$2"
|
|
282
|
-
local review_file="$3"
|
|
283
|
-
local notes_file="$4"
|
|
284
|
-
local slug="$5"
|
|
285
|
-
local timestamp="$6"
|
|
286
|
-
local capability_id="$7"
|
|
287
|
-
local owner="${USER:-AI Agent}"
|
|
288
|
-
local task_profile
|
|
289
|
-
local template_file=".claude/templates/contract.template.md"
|
|
290
|
-
local tmp_file
|
|
291
|
-
|
|
292
|
-
task_profile="$(plan_task_profile_from_file "$plan_file")"
|
|
293
|
-
|
|
294
|
-
if [[ ! -f "$template_file" ]]; then
|
|
295
|
-
mkdir -p .claude/templates
|
|
296
|
-
cat > "$template_file" <<'CONTRACT_TEMPLATE_EOF'
|
|
297
|
-
# Task Contract: {{TASK_SLUG}}
|
|
298
|
-
|
|
299
|
-
> **Status**: Pending
|
|
300
|
-
> **Plan**: {{PLAN_FILE}}
|
|
301
|
-
> **Task Profile**: {{TASK_PROFILE}}
|
|
302
|
-
> **Owner**: {{OWNER}}
|
|
303
|
-
> **Capability ID**: {{CAPABILITY_ID}}
|
|
304
|
-
> **Last Updated**: {{TIMESTAMP}}
|
|
305
|
-
> **Review File**: `{{REVIEW_FILE}}`
|
|
306
|
-
> **Notes File**: `{{NOTES_FILE}}`
|
|
307
|
-
|
|
308
|
-
## Goal
|
|
309
|
-
|
|
310
|
-
Describe the exact outcome this task must deliver.
|
|
311
|
-
|
|
312
|
-
## Scope
|
|
313
|
-
|
|
314
|
-
- In scope:
|
|
315
|
-
- Out of scope:
|
|
316
|
-
|
|
317
|
-
## Workflow Inventory
|
|
318
|
-
|
|
319
|
-
- Source plan: `{{PLAN_FILE}}`
|
|
320
|
-
- Deferred-goal ledger: `tasks/todos.md`
|
|
321
|
-
- Review file: `{{REVIEW_FILE}}`
|
|
322
|
-
- Notes file: `{{NOTES_FILE}}`
|
|
323
|
-
- Checks file: `.ai/harness/checks/latest.json`
|
|
324
|
-
- Run snapshots: `.ai/harness/runs/`
|
|
325
|
-
- Scope gate: edit only paths listed under `allowed_paths`; update this contract before widening scope.
|
|
326
|
-
- Completion evidence: `scripts/verify-sprint.sh` reports this contract's direct checks and declared scope. Then perform a fresh semantic impact review.
|
|
327
|
-
|
|
328
|
-
## Allowed Paths
|
|
329
|
-
|
|
330
|
-
```yaml
|
|
331
|
-
allowed_paths:
|
|
332
|
-
- plans/
|
|
333
|
-
- tasks/todos.md
|
|
334
|
-
- {{CONTRACT_FILE}}
|
|
335
|
-
- {{REVIEW_FILE}}
|
|
336
|
-
- {{NOTES_FILE}}
|
|
337
|
-
- .ai/context/capabilities.json
|
|
338
|
-
- .claude/templates/
|
|
339
|
-
- src/
|
|
340
|
-
- tests/
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
## Delegation Contract
|
|
344
|
-
|
|
345
|
-
```yaml
|
|
346
|
-
delegation:
|
|
347
|
-
budget:
|
|
348
|
-
tokens: null
|
|
349
|
-
tool_calls: null
|
|
350
|
-
wall_time_minutes: null
|
|
351
|
-
permission_scope:
|
|
352
|
-
mode: inherit_allowed_paths
|
|
353
|
-
writable_paths: []
|
|
354
|
-
network: inherited
|
|
355
|
-
roles:
|
|
356
|
-
parent:
|
|
357
|
-
mode: narrate_and_gatekeep
|
|
358
|
-
purpose: approval_checkpoint_owner
|
|
359
|
-
explorer:
|
|
360
|
-
mode: read_only
|
|
361
|
-
purpose: codebase_research
|
|
362
|
-
worker:
|
|
363
|
-
mode: edit_within_allowed_paths
|
|
364
|
-
purpose: implementation
|
|
365
|
-
verifier:
|
|
366
|
-
mode: read_only
|
|
367
|
-
purpose: exit_criteria_review
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
## Exit Criteria (Machine Verifiable)
|
|
371
|
-
|
|
372
|
-
```yaml
|
|
373
|
-
exit_criteria:
|
|
374
|
-
files_exist:
|
|
375
|
-
- src/modules/{{TASK_SLUG}}/index.ts
|
|
376
|
-
- {{NOTES_FILE}}
|
|
377
|
-
tests_pass:
|
|
378
|
-
- path: tests/unit/{{TASK_SLUG}}.test.ts
|
|
379
|
-
commands_succeed:
|
|
380
|
-
- bun run typecheck
|
|
381
|
-
files_contain:
|
|
382
|
-
- path: src/modules/{{TASK_SLUG}}/index.ts
|
|
383
|
-
pattern: "export"
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
## Acceptance Notes (Human Review)
|
|
387
|
-
|
|
388
|
-
- Functional behavior:
|
|
389
|
-
- Edge cases:
|
|
390
|
-
- Regression risks:
|
|
391
|
-
|
|
392
|
-
## Rollback Point
|
|
393
|
-
|
|
394
|
-
- Commit / checkpoint:
|
|
395
|
-
- Revert strategy:
|
|
396
|
-
CONTRACT_TEMPLATE_EOF
|
|
397
|
-
fi
|
|
398
|
-
|
|
399
|
-
tmp_file="$(mktemp)"
|
|
400
|
-
sed \
|
|
401
|
-
-e "s/{{TASK_SLUG}}/${slug}/g" \
|
|
402
|
-
-e "s|{{PLAN_FILE}}|${plan_file}|g" \
|
|
403
|
-
-e "s|{{TASK_PROFILE}}|${task_profile}|g" \
|
|
404
|
-
-e "s|{{CONTRACT_FILE}}|${contract_file}|g" \
|
|
405
|
-
-e "s|{{REVIEW_FILE}}|${review_file}|g" \
|
|
406
|
-
-e "s|{{NOTES_FILE}}|${notes_file}|g" \
|
|
407
|
-
-e "s|{{CAPABILITY_ID}}|${capability_id}|g" \
|
|
408
|
-
-e "s/{{OWNER}}/${owner}/g" \
|
|
409
|
-
-e "s/{{TIMESTAMP}}/${timestamp}/g" \
|
|
410
|
-
"$template_file" \
|
|
411
|
-
| sed \
|
|
412
|
-
-e "s|tasks/contracts/${slug}\\.contract\\.md|${contract_file}|g" \
|
|
413
|
-
-e "s|tasks/reviews/${slug}\\.review\\.md|${review_file}|g" \
|
|
414
|
-
-e "s|tasks/notes/${slug}\\.notes\\.md|${notes_file}|g" \
|
|
415
|
-
> "$tmp_file"
|
|
416
|
-
mv "$tmp_file" "$contract_file"
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
render_implementation_notes_file() {
|
|
420
|
-
local plan_file="$1"
|
|
421
|
-
local contract_file="$2"
|
|
422
|
-
local review_file="$3"
|
|
423
|
-
local notes_file="$4"
|
|
424
|
-
local slug="$5"
|
|
425
|
-
local timestamp="$6"
|
|
426
|
-
local template_file=".claude/templates/implementation-notes.template.md"
|
|
427
|
-
local tmp_file
|
|
428
|
-
|
|
429
|
-
if [[ ! -f "$template_file" ]]; then
|
|
430
|
-
mkdir -p .claude/templates
|
|
431
|
-
cat > "$template_file" <<'NOTES_TEMPLATE_EOF'
|
|
432
|
-
# Implementation Notes: {{TASK_SLUG}}
|
|
433
|
-
|
|
434
|
-
> **Status**: Active
|
|
435
|
-
> **Plan**: {{PLAN_FILE}}
|
|
436
|
-
> **Contract**: {{CONTRACT_FILE}}
|
|
437
|
-
> **Review**: {{REVIEW_FILE}}
|
|
438
|
-
> **Last Updated**: {{TIMESTAMP}}
|
|
439
|
-
> **Lifecycle**: notes
|
|
440
|
-
|
|
441
|
-
## Design Decisions
|
|
442
|
-
|
|
443
|
-
- ...
|
|
444
|
-
|
|
445
|
-
## Deviations From Plan Or Spec
|
|
446
|
-
|
|
447
|
-
- None recorded.
|
|
448
|
-
|
|
449
|
-
## Tradeoffs Considered
|
|
450
|
-
|
|
451
|
-
| Option | Decision | Reason |
|
|
452
|
-
|--------|----------|--------|
|
|
453
|
-
| ... | ... | ... |
|
|
454
|
-
|
|
455
|
-
## Open Questions
|
|
456
|
-
|
|
457
|
-
- None.
|
|
458
|
-
|
|
459
|
-
## Evidence Links
|
|
460
|
-
|
|
461
|
-
- Checks: `.ai/harness/checks/latest.json`
|
|
462
|
-
- Run snapshots: `.ai/harness/runs/`
|
|
463
|
-
|
|
464
|
-
## Promotion Candidates
|
|
465
|
-
|
|
466
|
-
- Promote to `tasks/lessons.md` only after a repeated correction or failure pattern.
|
|
467
|
-
- Promote to `docs/researches/` only when it is durable repo knowledge with evidence.
|
|
468
|
-
- Promote to harness asset files only after verification across more than one task or fixture.
|
|
469
|
-
NOTES_TEMPLATE_EOF
|
|
470
|
-
fi
|
|
471
|
-
|
|
472
|
-
tmp_file="$(mktemp)"
|
|
473
|
-
sed \
|
|
474
|
-
-e "s/{{TASK_SLUG}}/${slug}/g" \
|
|
475
|
-
-e "s|{{PLAN_FILE}}|${plan_file}|g" \
|
|
476
|
-
-e "s|{{CONTRACT_FILE}}|${contract_file}|g" \
|
|
477
|
-
-e "s|{{REVIEW_FILE}}|${review_file}|g" \
|
|
478
|
-
-e "s/{{TIMESTAMP}}/${timestamp}/g" \
|
|
479
|
-
"$template_file" > "$tmp_file"
|
|
480
|
-
mv "$tmp_file" "$notes_file"
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
# Delegate to workflow-state.sh if available; inline fallback otherwise.
|
|
484
|
-
# This ensures a single source of truth for task-state JSON generation.
|
|
485
|
-
if [[ "$_HAS_WF_LIB" -eq 0 ]]; then
|
|
486
|
-
workflow_sync_task_state_from_todo() {
|
|
487
|
-
local todo_file="${1:-tasks/todos.md}"
|
|
488
|
-
local state_file="${2:-.claude/.task-state.json}"
|
|
489
|
-
local source_plan="${3:-}"
|
|
490
|
-
local timestamp
|
|
491
|
-
local tmp_state
|
|
492
|
-
local total=0
|
|
493
|
-
local done=0
|
|
494
|
-
local promoted_in_progress=0
|
|
495
|
-
local first=1
|
|
496
|
-
|
|
497
|
-
mkdir -p "$(dirname "$state_file")"
|
|
498
|
-
timestamp="$(date '+%Y-%m-%dT%H:%M:%S%z')"
|
|
499
|
-
|
|
500
|
-
{
|
|
501
|
-
echo "{"
|
|
502
|
-
printf ' "done_tasks": 0,\n'
|
|
503
|
-
printf ' "total_tasks": 0,\n'
|
|
504
|
-
printf ' "source_plan": "%s",\n' "$(workflow_json_escape "${source_plan:-}")"
|
|
505
|
-
printf ' "updated_at": "%s",\n' "$(workflow_json_escape "$timestamp")"
|
|
506
|
-
echo ' "tasks": ['
|
|
507
|
-
|
|
508
|
-
while IFS= read -r line; do
|
|
509
|
-
printf '%s\n' "$line" | grep -Eq '^[[:space:]]*-[[:space:]]\[[ xX]\][[:space:]]+' || continue
|
|
510
|
-
total=$((total + 1))
|
|
511
|
-
local desc
|
|
512
|
-
desc="$(printf '%s' "$line" | sed -E 's/^[[:space:]]*-[[:space:]]\[[ xX]\][[:space:]]+//')"
|
|
513
|
-
local status="pending"
|
|
514
|
-
local passes="false"
|
|
515
|
-
|
|
516
|
-
if [[ "$line" =~ \[[xX]\] ]]; then
|
|
517
|
-
status="completed"
|
|
518
|
-
passes="true"
|
|
519
|
-
done=$((done + 1))
|
|
520
|
-
elif [[ "$promoted_in_progress" -eq 0 ]]; then
|
|
521
|
-
status="in_progress"
|
|
522
|
-
promoted_in_progress=1
|
|
523
|
-
fi
|
|
524
|
-
|
|
525
|
-
if [[ "$first" -eq 0 ]]; then
|
|
526
|
-
echo ","
|
|
527
|
-
fi
|
|
528
|
-
first=0
|
|
529
|
-
|
|
530
|
-
printf ' {"id":"task-%s","desc":"%s","status":"%s","passes":%s,"verification_evidence":[]}' \
|
|
531
|
-
"$total" \
|
|
532
|
-
"$(workflow_json_escape "$desc")" \
|
|
533
|
-
"$status" \
|
|
534
|
-
"$passes"
|
|
535
|
-
done < "$todo_file"
|
|
536
|
-
|
|
537
|
-
echo
|
|
538
|
-
echo " ]"
|
|
539
|
-
echo "}"
|
|
540
|
-
} > "$state_file"
|
|
541
|
-
|
|
542
|
-
tmp_state="$(mktemp)"
|
|
543
|
-
awk -v done="$done" -v total="$total" '
|
|
544
|
-
{
|
|
545
|
-
if ($0 ~ /"done_tasks":/) {
|
|
546
|
-
printf " \"done_tasks\": %s,\n", done
|
|
547
|
-
} else if ($0 ~ /"total_tasks":/) {
|
|
548
|
-
printf " \"total_tasks\": %s,\n", total
|
|
549
|
-
} else {
|
|
550
|
-
print
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
' "$state_file" > "$tmp_state"
|
|
554
|
-
mv "$tmp_state" "$state_file"
|
|
555
|
-
}
|
|
556
|
-
fi
|
|
557
|
-
|
|
558
|
-
plan_file=""
|
|
559
|
-
while [[ $# -gt 0 ]]; do
|
|
560
|
-
case "$1" in
|
|
561
|
-
--plan)
|
|
562
|
-
[[ -n "${2:-}" ]] || { echo "Error: --plan requires a value" >&2; usage; exit 1; }
|
|
563
|
-
plan_file="$2"
|
|
564
|
-
shift 2
|
|
565
|
-
;;
|
|
566
|
-
--help|-h)
|
|
567
|
-
usage
|
|
568
|
-
exit 0
|
|
569
|
-
;;
|
|
570
|
-
*)
|
|
571
|
-
echo "Unknown argument: $1" >&2
|
|
572
|
-
usage
|
|
573
|
-
exit 1
|
|
574
|
-
;;
|
|
575
|
-
esac
|
|
576
|
-
done
|
|
577
|
-
|
|
578
|
-
if [[ -z "$plan_file" ]]; then
|
|
579
|
-
echo "--plan is required" >&2
|
|
580
|
-
usage
|
|
581
|
-
exit 1
|
|
582
|
-
fi
|
|
583
|
-
|
|
584
|
-
if [[ ! -f "$plan_file" ]]; then
|
|
585
|
-
echo "Plan file not found: $plan_file" >&2
|
|
586
|
-
exit 1
|
|
587
|
-
fi
|
|
588
|
-
|
|
589
|
-
status="$(extract_status "$plan_file")"
|
|
590
|
-
if [[ "$status" != "Approved" ]]; then
|
|
591
|
-
echo "Plan status must be Approved before extraction (current: ${status:-unknown})." >&2
|
|
592
|
-
exit 1
|
|
593
|
-
fi
|
|
594
|
-
|
|
595
|
-
if ! evidence_error="$(plan_evidence_contract_error "$plan_file")"; then
|
|
596
|
-
echo "Plan Evidence Contract is incomplete in $plan_file:" >&2
|
|
597
|
-
printf '%s\n' "$evidence_error" >&2
|
|
598
|
-
exit 1
|
|
599
|
-
fi
|
|
600
|
-
|
|
601
|
-
maybe_start_contract_worktree "$plan_file"
|
|
602
|
-
|
|
603
|
-
mkdir -p tasks/archive
|
|
604
|
-
mkdir -p tasks/contracts
|
|
605
|
-
mkdir -p tasks/reviews
|
|
606
|
-
mkdir -p tasks/notes
|
|
607
|
-
mkdir -p .claude
|
|
608
|
-
mkdir -p .ai/context
|
|
609
|
-
mkdir -p .ai/harness/checks
|
|
610
|
-
mkdir -p .ai/harness/session .ai/harness/controller/packets .ai/harness/projections .ai/harness/transfers
|
|
611
|
-
mkdir -p .ai/harness/failures
|
|
612
|
-
mkdir -p .ai/harness/planning
|
|
613
|
-
mkdir -p .ai/harness/runs
|
|
614
|
-
|
|
615
|
-
timestamp="$(date +%Y%m%d-%H%M)"
|
|
616
|
-
timestamp_human="$(date '+%Y-%m-%d %H:%M')"
|
|
617
|
-
plan_base="$(basename "$plan_file")"
|
|
618
|
-
slug="$(plan_slug_from_path "$plan_file")"
|
|
619
|
-
original_artifact_stem="$(plan_original_artifact_stem_from_path "$plan_file")"
|
|
620
|
-
artifact_stem="$(plan_artifact_stem_from_path "$plan_file")"
|
|
621
|
-
contract_file="tasks/contracts/${artifact_stem}.contract.md"
|
|
622
|
-
review_file="tasks/reviews/${artifact_stem}.review.md"
|
|
623
|
-
notes_file="tasks/notes/${artifact_stem}.notes.md"
|
|
624
|
-
previous_source_plan="$(get_todo_source_plan || true)"
|
|
625
|
-
parent_run_id="${HOOK_RUN_ID:-${CLAUDE_RUN_ID:-${CODEX_RUN_ID:-run-${timestamp}}}}"
|
|
626
|
-
capability_id="$(extract_capability_id "$plan_file")"
|
|
627
|
-
capability_id="${capability_id:-root}"
|
|
628
|
-
|
|
629
|
-
rewrite_plan_artifact_references "$plan_file" "$original_artifact_stem" "$artifact_stem"
|
|
630
|
-
|
|
631
|
-
if [[ -f "tasks/todos.md" ]] \
|
|
632
|
-
&& grep -q '[^[:space:]]' tasks/todos.md \
|
|
633
|
-
&& ! grep -Eq '^> \*\*Status\*\*:[[:space:]]*Backlog[[:space:]]*$' tasks/todos.md; then
|
|
634
|
-
archive_file="$(unique_archive_path "tasks/archive/todo-${timestamp}-${slug}.md")"
|
|
635
|
-
{
|
|
636
|
-
echo "> **Archived**: $(date '+%Y-%m-%d %H:%M')"
|
|
637
|
-
echo "> **Related Plan**: ${plan_file}"
|
|
638
|
-
echo "> **Outcome**: Converted to deferred-goal ledger"
|
|
639
|
-
echo "> **Source Plan**: ${previous_source_plan:-"(none)"}"
|
|
640
|
-
echo "> **Parent Run ID**: ${parent_run_id}"
|
|
641
|
-
echo
|
|
642
|
-
cat tasks/todos.md
|
|
643
|
-
} > "$archive_file"
|
|
644
|
-
fi
|
|
645
|
-
|
|
646
|
-
if [[ ! -f "tasks/todos.md" ]] || ! grep -Eq '^> \*\*Status\*\*:[[:space:]]*Backlog[[:space:]]*$' tasks/todos.md; then
|
|
647
|
-
{
|
|
648
|
-
echo "# Deferred Goal Ledger"
|
|
649
|
-
echo
|
|
650
|
-
echo "> **Status**: Backlog"
|
|
651
|
-
echo "> **Updated**: ${timestamp_human}"
|
|
652
|
-
echo "> **Scope**: Medium/long-term goals deferred from active plan execution"
|
|
653
|
-
echo
|
|
654
|
-
echo "Current plan tasks live in \`${plan_file}\` under \`## Task Breakdown\`."
|
|
655
|
-
echo "Do not duplicate that execution checklist here. Record only work intentionally deferred beyond this slice, with the tradeoff and revisit trigger."
|
|
656
|
-
echo
|
|
657
|
-
echo "## Deferred Goals"
|
|
658
|
-
echo
|
|
659
|
-
echo "| Goal | Why Deferred | Tradeoff | Revisit Trigger |"
|
|
660
|
-
echo "|------|--------------|----------|-----------------|"
|
|
661
|
-
echo "| (none) | No deferred medium/long-term goal recorded for this projection. | Keep this sprint bounded. | Add a row when a real follow-up is postponed. |"
|
|
662
|
-
} > tasks/todos.md
|
|
663
|
-
else
|
|
664
|
-
todo_tmp="$(mktemp)"
|
|
665
|
-
awk -v timestamp_human="$timestamp_human" -v plan_file="$plan_file" '
|
|
666
|
-
/^\> \*\*Updated\*\*:/ {
|
|
667
|
-
print "> **Updated**: " timestamp_human
|
|
668
|
-
next
|
|
669
|
-
}
|
|
670
|
-
/^Current plan tasks live in `/ {
|
|
671
|
-
print "Current plan tasks live in `" plan_file "` under `## Task Breakdown`."
|
|
672
|
-
next
|
|
673
|
-
}
|
|
674
|
-
{ print }
|
|
675
|
-
' tasks/todos.md > "$todo_tmp"
|
|
676
|
-
mv "$todo_tmp" tasks/todos.md
|
|
677
|
-
fi
|
|
678
|
-
|
|
679
|
-
rm -f .claude/.task-state.json
|
|
680
|
-
|
|
681
|
-
if [[ -f ".claude/templates/review.template.md" ]]; then
|
|
682
|
-
:
|
|
683
|
-
else
|
|
684
|
-
mkdir -p .claude/templates
|
|
685
|
-
cat > .claude/templates/review.template.md <<'REVIEW_TEMPLATE_EOF'
|
|
686
|
-
# Task Review: {{TASK_SLUG}}
|
|
687
|
-
|
|
688
|
-
> **Status**: Pending
|
|
689
|
-
> **Plan**: {{PLAN_FILE}}
|
|
690
|
-
> **Contract**: {{CONTRACT_FILE}}
|
|
691
|
-
> **Notes File**: {{NOTES_FILE}}
|
|
692
|
-
> **Checks File**: {{CHECKS_FILE}}
|
|
693
|
-
> **Last Updated**: {{TIMESTAMP}}
|
|
694
|
-
> **Summary**:
|
|
695
|
-
|
|
696
|
-
## Semantic Impact Review
|
|
697
|
-
|
|
698
|
-
- User intent:
|
|
699
|
-
- Affected domains and downstream consumers:
|
|
700
|
-
- State transitions and persistence/restart impact:
|
|
701
|
-
- Missing impact areas or uncertainty:
|
|
702
|
-
- Residual risks and recovery:
|
|
703
|
-
|
|
704
|
-
## Mode Evidence
|
|
705
|
-
|
|
706
|
-
- Selected route:
|
|
707
|
-
- P1/P2/P3 evidence:
|
|
708
|
-
- Root cause or plan evidence:
|
|
709
|
-
|
|
710
|
-
## Verification Evidence
|
|
711
|
-
|
|
712
|
-
- Focused/full checks:
|
|
713
|
-
- Commands run:
|
|
714
|
-
- Manual checks:
|
|
715
|
-
- Supporting artifacts:
|
|
716
|
-
- Implementation notes reviewed:
|
|
717
|
-
- Run snapshot:
|
|
718
|
-
|
|
719
|
-
## Scenario Evidence
|
|
720
|
-
|
|
721
|
-
- ...
|
|
722
|
-
|
|
723
|
-
## Residual Risks / Follow-ups
|
|
724
|
-
|
|
725
|
-
- ...
|
|
726
|
-
|
|
727
|
-
## Failing Items
|
|
728
|
-
|
|
729
|
-
- ...
|
|
730
|
-
|
|
731
|
-
## Retest Steps
|
|
732
|
-
|
|
733
|
-
- Re-run:
|
|
734
|
-
- Re-check:
|
|
735
|
-
|
|
736
|
-
## Summary
|
|
737
|
-
|
|
738
|
-
- ...
|
|
739
|
-
REVIEW_TEMPLATE_EOF
|
|
740
|
-
fi
|
|
741
|
-
|
|
742
|
-
render_contract_file "$plan_file" "$contract_file" "$review_file" "$notes_file" "$slug" "$timestamp_human" "$capability_id"
|
|
743
|
-
render_implementation_notes_file "$plan_file" "$contract_file" "$review_file" "$notes_file" "$slug" "$timestamp_human"
|
|
744
|
-
sed \
|
|
745
|
-
-e "s/{{TASK_SLUG}}/${slug}/g" \
|
|
746
|
-
-e "s|{{PLAN_FILE}}|${plan_file}|g" \
|
|
747
|
-
-e "s|{{CONTRACT_FILE}}|${contract_file}|g" \
|
|
748
|
-
-e "s|{{NOTES_FILE}}|${notes_file}|g" \
|
|
749
|
-
-e "s|{{CHECKS_FILE}}|.ai/harness/checks/latest.json|g" \
|
|
750
|
-
-e "s/{{TIMESTAMP}}/${timestamp_human}/g" \
|
|
751
|
-
.claude/templates/review.template.md > "$review_file"
|
|
752
|
-
|
|
753
|
-
if [[ ! -f ".ai/harness/checks/latest.json" ]]; then
|
|
754
|
-
echo "{}" > .ai/harness/checks/latest.json
|
|
755
|
-
fi
|
|
756
|
-
|
|
757
|
-
set_plan_status "$plan_file" "Executing"
|
|
758
|
-
if declare -F set_active_plan >/dev/null 2>&1; then
|
|
759
|
-
set_active_plan "$plan_file"
|
|
760
|
-
else
|
|
761
|
-
mkdir -p .ai/harness .claude
|
|
762
|
-
printf '%s' "$plan_file" > .ai/harness/active-plan
|
|
763
|
-
printf '%s' "$plan_file" > .claude/.active-plan
|
|
764
|
-
pwd -P > .ai/harness/active-worktree
|
|
765
|
-
fi
|
|
766
|
-
|
|
767
|
-
if declare -F workflow_clear_pending_orchestration >/dev/null 2>&1; then
|
|
768
|
-
workflow_clear_pending_orchestration
|
|
769
|
-
else
|
|
770
|
-
rm -f .ai/harness/planning/pending.json
|
|
771
|
-
fi
|
|
772
|
-
|
|
773
|
-
echo "Prepared sprint artifacts from $plan_file"
|
|
774
|
-
echo "Left tasks/todos.md as deferred-goal ledger; execute the plan's own ## Task Breakdown."
|
|
4
|
+
exec "$SCRIPT_DIR/lib/run-forge-helper.sh" "plan-to-todo.sh" "$@"
|