@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.
Files changed (175) hide show
  1. package/AGENTS.md +2 -0
  2. package/CHANGELOG.md +26 -0
  3. package/CLAUDE.md +2 -0
  4. package/THIRD_PARTY_NOTICES.md +1 -1
  5. package/agents/openai.yaml +1 -1
  6. package/assets/partials-agents/02-operating-mode.partial.md +2 -0
  7. package/assets/plugin-registry.v1.json +3 -3
  8. package/assets/skill-version.json +2 -2
  9. package/assets/templates/helpers/check-architecture-sync.sh +17 -0
  10. package/assets/templates/helpers/inspect-project-state.ts +8 -6
  11. package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
  12. package/assets/templates/helpers/workflow-contract.ts +5 -1
  13. package/docs/architecture/CURRENT.md +12 -4
  14. package/docs/forge-plugin-management.md +1 -1
  15. package/docs/operations/controller-performance-and-502.md +19 -0
  16. package/docs/operations/homebrew.md +2 -2
  17. package/package.json +5 -2
  18. package/scripts/architecture-event.ts +2 -820
  19. package/scripts/architecture-queue.sh +2 -645
  20. package/scripts/archive-architecture-request.sh +2 -242
  21. package/scripts/archive-workflow.sh +1 -291
  22. package/scripts/benchmark-work-efficiency.ts +0 -0
  23. package/scripts/capability-config.ts +2 -392
  24. package/scripts/capability-resolver.ts +2 -503
  25. package/scripts/capture-plan.sh +1 -332
  26. package/scripts/check-agent-tooling.sh +2 -1531
  27. package/scripts/check-architecture-sync.sh +2 -302
  28. package/scripts/check-brain-manifest.sh +2 -253
  29. package/scripts/check-context-files.sh +2 -47
  30. package/scripts/check-deploy-sql-order.sh +2 -115
  31. package/scripts/check-runtime-architecture.mjs +243 -16
  32. package/scripts/check-skill-version.ts +3 -191
  33. package/scripts/check-source-duplication.mjs +61 -0
  34. package/scripts/check-stable-baseline.ts +0 -0
  35. package/scripts/check-task-sync.sh +2 -63
  36. package/scripts/check-task-workflow.sh +2 -1000
  37. package/scripts/codex-handoff-resume.sh +2 -267
  38. package/scripts/context-contract-sync.sh +2 -514
  39. package/scripts/contract-run.ts +2 -463
  40. package/scripts/contract-worktree.sh +1 -702
  41. package/scripts/ensure-task-workflow.sh +1 -1192
  42. package/scripts/inspect-project-state.ts +4 -279
  43. package/scripts/lib/project-init-lib.sh +7 -2
  44. package/scripts/lib/run-forge-helper.sh +19 -0
  45. package/scripts/lib/run-forge-helper.ts +26 -0
  46. package/scripts/migrate-project-template.sh +1 -33
  47. package/scripts/migrate-workflow-docs.ts +4 -412
  48. package/scripts/new-plan.sh +1 -180
  49. package/scripts/new-spec.sh +1 -47
  50. package/scripts/new-sprint.sh +1 -46
  51. package/scripts/plan-to-todo.sh +1 -771
  52. package/scripts/prepare-codex-handoff.sh +2 -201
  53. package/scripts/prepare-handoff.sh +1 -78
  54. package/scripts/refresh-current-status.sh +2 -467
  55. package/scripts/run-governed-gate.ts +3 -0
  56. package/scripts/select-agent-context-blocks.sh +2 -64
  57. package/scripts/ship-worktrees.sh +1 -531
  58. package/scripts/sprint-backlog.sh +1 -834
  59. package/scripts/stage-runtime-release.ts +2 -1
  60. package/scripts/summarize-failures.sh +2 -123
  61. package/scripts/switch-plan.sh +1 -150
  62. package/scripts/sync-brain-docs.sh +2 -379
  63. package/scripts/sync-generated-authority.mjs +175 -0
  64. package/scripts/verify-contract.sh +2 -593
  65. package/scripts/verify-sprint.sh +1 -500
  66. package/scripts/workflow-contract.ts +4 -201
  67. package/scripts/workstream-sync.sh +2 -261
  68. package/src/cli/agent-jobs/executor-health.ts +1 -1
  69. package/src/cli/commands/plugin.ts +12 -3
  70. package/src/cli/controller/check-runner.ts +7 -2
  71. package/src/cli/controller/context-pack.ts +46 -21
  72. package/src/cli/github/contracts.ts +16 -0
  73. package/src/cli/github/github.ts +2 -16
  74. package/src/cli/github/session.ts +2 -1
  75. package/src/cli/local-bridge/facade-api.ts +37 -47
  76. package/src/cli/local-bridge/server.ts +2 -2
  77. package/src/cli/mcp/legacy-tool-service.ts +10 -33
  78. package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
  79. package/src/cli/mcp/repository-tools.ts +125 -101
  80. package/src/cli/mcp/server.ts +57 -13
  81. package/src/cli/mcp/tool-contract.ts +14 -0
  82. package/src/cli/mcp/toolset.ts +2 -2
  83. package/src/cli/mcp/transports/http.ts +23 -0
  84. package/src/cli/repositories/command-classifier.ts +2 -2
  85. package/src/cli/repositories/command-executor.ts +24 -6
  86. package/src/cli/repositories/repository-snapshot.ts +5 -2
  87. package/src/cli/repositories/structured-git.ts +57 -3
  88. package/src/cli/repository/inspector.ts +11 -3
  89. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  90. package/src/runtime/context/semantic-navigation-contract.ts +61 -0
  91. package/src/runtime/context/semantic-navigation.ts +9 -61
  92. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +69 -29
  93. package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
  94. package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
  95. package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
  96. package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
  97. package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
  98. package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
  99. package/src/runtime/control-plane/execution/work-handle-authority.ts +150 -0
  100. package/src/runtime/control-plane/execution/work-handle-store.ts +1 -1
  101. package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
  102. package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
  103. package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
  104. package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
  105. package/src/runtime/control-plane/execution/work-task-receipt.ts +4 -43
  106. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +13 -3
  107. package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
  108. package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
  109. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
  110. package/src/runtime/control-plane/facade/controller-round-relay.ts +164 -37
  111. package/src/runtime/control-plane/facade/controller-session-store.ts +183 -24
  112. package/src/runtime/control-plane/facade/goal-workloop-access.ts +15 -1
  113. package/src/runtime/control-plane/facade/goal-workloop.ts +329 -148
  114. package/src/runtime/control-plane/facade/index.ts +2 -0
  115. package/src/runtime/control-plane/facade/plan-contract-store.ts +90 -22
  116. package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
  117. package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
  118. package/src/runtime/control-plane/facade/types.ts +68 -5
  119. package/src/runtime/control-plane/facade/work-contract-store.ts +3 -209
  120. package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
  121. package/src/runtime/control-plane/global-scheduler/maintenance.ts +14 -7
  122. package/src/runtime/control-plane/global-scheduler/scheduler.ts +5 -1
  123. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +13 -0
  124. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +15 -6
  125. package/src/runtime/control-plane/launcher/launch-reservation-store.ts +54 -5
  126. package/src/runtime/control-plane/launcher/thin-launcher.ts +56 -7
  127. package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
  128. package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
  129. package/src/runtime/control-plane/routing/route-policy.ts +18 -6
  130. package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
  131. package/src/runtime/evidence/process-check-execution.ts +18 -0
  132. package/src/runtime/execution/jobs/child-reference.ts +6 -2
  133. package/src/runtime/execution/process-runtime/check-result.ts +53 -18
  134. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
  135. package/src/runtime/execution/process-runtime/command-facade.ts +39 -17
  136. package/src/runtime/execution/process-runtime/lightweight-managed.ts +20 -3
  137. package/src/runtime/execution/process-runtime/persisted-check.ts +4 -1
  138. package/src/runtime/execution/process-runtime/runtime.ts +10 -0
  139. package/src/runtime/execution/process-runtime/types.ts +2 -12
  140. package/src/runtime/execution/work-activity.ts +21 -0
  141. package/src/runtime/execution/workers/executor.ts +18 -13
  142. package/src/runtime/gateway/mcp/execution-tools.ts +35 -2930
  143. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
  144. package/src/runtime/gateway/mcp/router.ts +2 -2
  145. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +21 -2
  146. package/src/runtime/gateway/mcp/runtime-tools.ts +815 -1015
  147. package/src/runtime/plugins/app-store-connect-adapter.ts +93 -28
  148. package/src/runtime/plugins/browser-adapter.ts +256 -1083
  149. package/src/runtime/plugins/browser-handoff-host.ts +2 -25
  150. package/src/runtime/plugins/browser-handoff.ts +18 -3
  151. package/src/runtime/plugins/browser-macos-bridge.ts +121 -16
  152. package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
  153. package/src/runtime/plugins/browser-native-session-service.ts +222 -0
  154. package/src/runtime/plugins/browser-runtime-contract.ts +2 -0
  155. package/src/runtime/plugins/browser-runtime.ts +10 -0
  156. package/src/runtime/plugins/browser-session-store.ts +121 -0
  157. package/src/runtime/plugins/browser-session-types.ts +98 -0
  158. package/src/runtime/plugins/desktop-operator-registration.ts +4 -4
  159. package/src/runtime/plugins/external-adapter.ts +92 -58
  160. package/src/runtime/plugins/macos-capability-broker.ts +0 -8
  161. package/src/runtime/plugins/store.ts +66 -9
  162. package/src/runtime/plugins/types.ts +3 -1
  163. package/src/runtime/recovery/maintenance-executor.ts +61 -25
  164. package/src/runtime/root/package-connector-service.ts +46 -4
  165. package/src/runtime/root/package-runtime-release.ts +3 -2
  166. package/src/runtime/root/package-runtime-service.ts +48 -3
  167. package/src/runtime/root/release-manifest.ts +137 -16
  168. package/src/runtime/root/release-materialize.ts +109 -35
  169. package/src/runtime/root/types.ts +10 -0
  170. package/src/runtime/standalone-recovery/core.ts +425 -194
  171. package/src/runtime/standalone-recovery/entry.ts +1 -1
  172. package/src/runtime/standalone-recovery/installer.ts +1 -1
  173. package/src/runtime/workflow/schedules/engine.ts +113 -87
  174. package/src/runtime/workflow/schedules/settlement.ts +26 -23
  175. package/src/runtime/workflow/schedules/store.ts +79 -10
@@ -1,516 +1,4 @@
1
1
  #!/bin/bash
2
2
  set -euo pipefail
3
-
4
- usage() {
5
- cat <<'USAGE_EOF'
6
- Usage:
7
- scripts/context-contract-sync.sh sync-latest
8
- scripts/context-contract-sync.sh sync-event --json '<event-json>'
9
- USAGE_EOF
10
- }
11
-
12
- repo="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
13
- repo="$(cd "$repo" && pwd)"
14
- cd "$repo"
15
-
16
- command_name="${1:-sync-latest}"
17
- shift || true
18
-
19
- event_json=""
20
- event_file=".ai/harness/architecture/events.jsonl"
21
-
22
- while [[ $# -gt 0 ]]; do
23
- case "$1" in
24
- --json)
25
- [[ -n "${2:-}" ]] || { echo "context-contract-sync: --json requires a value" >&2; exit 2; }
26
- event_json="$2"
27
- shift 2
28
- ;;
29
- --help|-h)
30
- usage
31
- exit 0
32
- ;;
33
- *)
34
- echo "context-contract-sync: unknown argument: $1" >&2
35
- usage
36
- exit 2
37
- ;;
38
- esac
39
- done
40
-
41
- architecture_event() {
42
- if command -v bun >/dev/null 2>&1 && [[ -f "scripts/architecture-event.ts" ]]; then
43
- bun scripts/architecture-event.ts "$@"
44
- return $?
45
- fi
46
- return 127
47
- }
48
-
49
- json_get() {
50
- local json_input="$1"
51
- local key="$2"
52
- local parsed=""
53
-
54
- if [[ -z "$json_input" ]]; then
55
- return 1
56
- fi
57
-
58
- if parsed="$(architecture_event json-get --key "$key" --json "$json_input" 2>/dev/null)"; then
59
- printf '%s' "$parsed"
60
- return 0
61
- fi
62
-
63
- if command -v jq >/dev/null 2>&1; then
64
- parsed="$(printf '%s' "$json_input" | jq -r ".$key // empty" 2>/dev/null || true)"
65
- fi
66
-
67
- if [[ -z "$parsed" ]] && command -v node >/dev/null 2>&1; then
68
- parsed="$(JSON_INPUT="$json_input" JSON_KEY="$key" node -e '
69
- const raw = process.env.JSON_INPUT || "";
70
- const key = process.env.JSON_KEY || "";
71
- try {
72
- const value = JSON.parse(raw)[key];
73
- if (value === undefined || value === null) process.exit(1);
74
- process.stdout.write(String(value));
75
- } catch {
76
- process.exit(1);
77
- }
78
- ' 2>/dev/null || true)"
79
- fi
80
-
81
- if [[ -z "$parsed" ]] && command -v bun >/dev/null 2>&1; then
82
- parsed="$(JSON_INPUT="$json_input" JSON_KEY="$key" bun -e '
83
- const raw = process.env.JSON_INPUT || "";
84
- const key = process.env.JSON_KEY || "";
85
- try {
86
- const value = JSON.parse(raw)[key];
87
- if (value === undefined || value === null) process.exit(1);
88
- process.stdout.write(String(value));
89
- } catch {
90
- process.exit(1);
91
- }
92
- ' 2>/dev/null || true)"
93
- fi
94
-
95
- [[ -n "$parsed" ]] || return 1
96
- printf '%s' "$parsed"
97
- }
98
-
99
- safe_token() {
100
- local value="$1"
101
- local parsed=""
102
-
103
- if parsed="$(architecture_event safe-token --value "$value" 2>/dev/null)"; then
104
- printf '%s' "$parsed"
105
- return 0
106
- fi
107
-
108
- value="$(printf '%s' "$value" | tr '[:upper:]' '[:lower:]')"
109
- value="$(printf '%s' "$value" | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-{2,}/-/g')"
110
- printf '%s' "${value:-root}"
111
- }
112
-
113
- derive_scope() {
114
- local block="$1"
115
- local derived=""
116
- local block_slug
117
- local domain_slug
118
- local capability_slug
119
- local architecture_module
120
- local workstream_dir
121
-
122
- if derived="$(architecture_event derive-scope --block "$block" 2>/dev/null)"; then
123
- printf '%s\n' "$derived"
124
- return 0
125
- fi
126
-
127
- block_slug="$(safe_token "$block")"
128
- domain_slug="$block_slug"
129
- capability_slug="_domain"
130
-
131
- IFS='/' read -r -a parts <<< "$block"
132
- if [[ "${#parts[@]}" -ge 2 ]]; then
133
- domain_slug="$(safe_token "${parts[0]}-${parts[1]}")"
134
- fi
135
- if [[ "${#parts[@]}" -gt 2 ]]; then
136
- local last_index
137
- last_index=$((${#parts[@]} - 1))
138
- capability_slug="$(safe_token "${parts[$last_index]}")"
139
- fi
140
-
141
- architecture_module="docs/architecture/modules/${domain_slug}/${capability_slug}.md"
142
- workstream_dir="tasks/workstreams/${domain_slug}/${capability_slug}"
143
- printf '%s\n%s\n%s\n%s\n' "$domain_slug" "$capability_slug" "$architecture_module" "$workstream_dir"
144
- }
145
-
146
- metadata_value() {
147
- local file="$1"
148
- local label="$2"
149
- awk -v label="$label" '
150
- $0 ~ "^> \\*\\*" label "\\*\\*:" {
151
- sub("^> \\*\\*" label "\\*\\*: ?", "")
152
- print
153
- exit
154
- }
155
- ' "$file" 2>/dev/null
156
- }
157
-
158
- format_active_workstreams() {
159
- local dir="$1"
160
- local count=0
161
- local file
162
- local status
163
- local current_slice
164
- local source_plan
165
-
166
- if [[ ! -d "$dir" ]]; then
167
- echo "- (none yet)"
168
- return 0
169
- fi
170
-
171
- while IFS= read -r file; do
172
- [[ -n "$file" ]] || continue
173
- status="$(metadata_value "$file" "Status")"
174
- current_slice="$(metadata_value "$file" "Current Slice")"
175
- source_plan="$(metadata_value "$file" "Source Plan")"
176
- echo "- \`${file}\`"
177
- echo " - status: ${status:-unknown}"
178
- echo " - current_slice: ${current_slice:-unknown}"
179
- echo " - source_plan: ${source_plan:-unknown}"
180
- count=$((count + 1))
181
- done < <(find "$dir" -maxdepth 1 -type f -name '*.md' 2>/dev/null | sort | head -5)
182
-
183
- if [[ "$count" -eq 0 ]]; then
184
- echo "- (none yet)"
185
- fi
186
- }
187
-
188
- validate_block() {
189
- local block="$1"
190
- case "$block" in
191
- ""|root|.|..|../*|*/../*|/*|*$'\n'*|*$'\r'*)
192
- return 1
193
- ;;
194
- esac
195
- [[ -e "$block" ]]
196
- }
197
-
198
- replace_contract_block() {
199
- local source_file="$1"
200
- local output_file="$2"
201
- local block_file="$3"
202
- local marker_state begins ends disorder
203
-
204
- # Refuse to rewrite when markers are unbalanced: a missing END would swallow
205
- # everything after BEGIN, and duplicate markers would duplicate the block.
206
- marker_state="$(awk '
207
- /^<!-- BEGIN ARCHITECTURE CONTRACT -->[[:space:]]*$/ { begins++; if (ends > 0) disorder = 1 }
208
- /^<!-- END ARCHITECTURE CONTRACT -->[[:space:]]*$/ { ends++; if (begins == 0) disorder = 1 }
209
- END { printf "%d %d %d", begins, ends, disorder }
210
- ' "$source_file")"
211
- read -r begins ends disorder <<< "$marker_state"
212
- if ! { [[ "$begins" -eq 0 && "$ends" -eq 0 ]] || [[ "$begins" -eq 1 && "$ends" -eq 1 && "$disorder" -eq 0 ]]; }; then
213
- echo "[ContextContractSync] ERROR: unbalanced ARCHITECTURE CONTRACT markers in $source_file (begin=$begins end=$ends); refusing to rewrite. Repair the markers manually, then re-run sync." >&2
214
- return 1
215
- fi
216
-
217
- awk -v block_file="$block_file" '
218
- BEGIN {
219
- while ((getline line < block_file) > 0) {
220
- block = block line "\n"
221
- }
222
- close(block_file)
223
- in_block = 0
224
- replaced = 0
225
- }
226
- /^<!-- BEGIN ARCHITECTURE CONTRACT -->[[:space:]]*$/ {
227
- printf "%s", block
228
- in_block = 1
229
- replaced = 1
230
- next
231
- }
232
- /^<!-- END ARCHITECTURE CONTRACT -->[[:space:]]*$/ {
233
- in_block = 0
234
- next
235
- }
236
- in_block == 0 { print }
237
- END {
238
- if (replaced == 0) {
239
- if (NR > 0) print ""
240
- printf "%s", block
241
- }
242
- }
243
- ' "$source_file" > "$output_file"
244
- }
245
-
246
- sync_context_map() {
247
- local block="$1"
248
- local domain_slug="$2"
249
- local capability_slug="$3"
250
- local capability_id="${4:-$block}"
251
- local contract_agents="${5:-$block/AGENTS.md}"
252
- local contract_claude="${6:-$block/CLAUDE.md}"
253
- local lsp_profile="${7:-typescript-lsp}"
254
- local context_map=".ai/context/context-map.json"
255
- local runtime=""
256
-
257
- if architecture_event sync-context-map \
258
- --context-map "$context_map" \
259
- --block "$block" \
260
- --capability-id "$capability_id" \
261
- --contract-agents "$contract_agents" \
262
- --contract-claude "$contract_claude" \
263
- --architecture-domain "$domain_slug" \
264
- --architecture-capability "$capability_slug" \
265
- --lsp-profile "$lsp_profile" 2>/dev/null; then
266
- return 0
267
- fi
268
-
269
- if command -v node >/dev/null 2>&1; then
270
- runtime="node"
271
- elif command -v bun >/dev/null 2>&1; then
272
- runtime="bun"
273
- else
274
- echo "[ContextContractSync] Context map update skipped: node or bun not found."
275
- return 0
276
- fi
277
-
278
- mkdir -p "$(dirname "$context_map")"
279
- if [[ ! -f "$context_map" ]]; then
280
- cat > "$context_map" <<'CONTEXT_EOF'
281
- {
282
- "version": 1,
283
- "profile": "stable-root-progressive-subdir",
284
- "functional_block_selector": {
285
- "script": "scripts/select-agent-context-blocks.sh",
286
- "config_file": ".ai/context/agent-context-blocks.txt",
287
- "env": "FORGE_CONTEXT_BLOCKS",
288
- "rule": "compatibility selector; capability registry is the source of truth"
289
- },
290
- "root_context_files": ["CLAUDE.md", "AGENTS.md"],
291
- "discoverable_contexts": []
292
- }
293
- CONTEXT_EOF
294
- fi
295
-
296
- CONTEXT_MAP="$context_map" BLOCK_PATH="$block" CAPABILITY_ID="$capability_id" CONTRACT_AGENTS="$contract_agents" CONTRACT_CLAUDE="$contract_claude" ARCH_DOMAIN="$domain_slug" ARCH_CAPABILITY="$capability_slug" LSP_PROFILE="$lsp_profile" "$runtime" <<'JS_EOF'
297
- const fs = require("fs");
298
- const path = process.env.CONTEXT_MAP;
299
- const block = process.env.BLOCK_PATH;
300
- const capabilityId = process.env.CAPABILITY_ID;
301
- const contractAgents = process.env.CONTRACT_AGENTS;
302
- const contractClaude = process.env.CONTRACT_CLAUDE;
303
- const domain = process.env.ARCH_DOMAIN;
304
- const capability = process.env.ARCH_CAPABILITY;
305
- const lspProfile = process.env.LSP_PROFILE || "typescript-lsp";
306
-
307
- let data;
308
- try {
309
- data = JSON.parse(fs.readFileSync(path, "utf8"));
310
- } catch {
311
- data = {
312
- version: 1,
313
- profile: "stable-root-progressive-subdir",
314
- root_context_files: ["CLAUDE.md", "AGENTS.md"],
315
- discoverable_contexts: []
316
- };
317
- }
318
-
319
- if (!Array.isArray(data.discoverable_contexts)) data.discoverable_contexts = [];
320
-
321
- for (const [fileName, entryPath] of [["CLAUDE.md", contractClaude], ["AGENTS.md", contractAgents]]) {
322
- const targetAgent = fileName === "CLAUDE.md" ? "claude" : "codex";
323
- if (!data.discoverable_contexts.some((entry) => entry && entry.path === entryPath)) {
324
- data.discoverable_contexts.push({
325
- path: entryPath,
326
- priority: "high",
327
- char_budget: 1000,
328
- purpose: "capability-contract",
329
- capability_id: capabilityId,
330
- functional_block: block,
331
- matched_prefix: block,
332
- architecture_domain: domain,
333
- architecture_capability: capability,
334
- target_agent: targetAgent,
335
- lsp_profile: lspProfile,
336
- doc_scope: "capability-contract",
337
- verification_hint: "record local commands here before implementation"
338
- });
339
- }
340
- }
341
-
342
- fs.writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`);
343
- JS_EOF
344
- }
345
-
346
- if [[ "$command_name" == "sync-latest" ]]; then
347
- event_json="$(tail -n 1 "$event_file" 2>/dev/null || true)"
348
- elif [[ "$command_name" != "sync-event" ]]; then
349
- echo "context-contract-sync: unknown command: $command_name" >&2
350
- usage
351
- exit 2
352
- fi
353
-
354
- if [[ -z "$event_json" ]]; then
355
- echo "[ContextContractSync] No architecture event to sync."
356
- exit 0
357
- fi
358
-
359
- functional_block="$(json_get "$event_json" "functional_block" || true)"
360
- capability_id="$(json_get "$event_json" "capability_id" || true)"
361
- matched_prefix="$(json_get "$event_json" "matched_prefix" || true)"
362
- file_path="$(json_get "$event_json" "file_path" || true)"
363
- severity="$(json_get "$event_json" "severity" || true)"
364
- change_type="$(json_get "$event_json" "change_type" || true)"
365
- request_file="$(json_get "$event_json" "request_file" || true)"
366
- event_ts="$(json_get "$event_json" "ts" || true)"
367
- architecture_domain="$(json_get "$event_json" "architecture_domain" || true)"
368
- architecture_capability="$(json_get "$event_json" "architecture_capability" || true)"
369
- architecture_module="$(json_get "$event_json" "architecture_module" || true)"
370
- workstream_dir="$(json_get "$event_json" "workstream_dir" || true)"
371
- contract_agents="$(json_get "$event_json" "contract_agents" || true)"
372
- contract_claude="$(json_get "$event_json" "contract_claude" || true)"
373
- lsp_profile="$(json_get "$event_json" "lsp_profile" || true)"
374
-
375
- if [[ ( -z "$capability_id" || "$capability_id" == "root" ) && -n "$file_path" && -f "scripts/capability-resolver.ts" ]] && command -v bun >/dev/null 2>&1; then
376
- resolver_json="$(bun scripts/capability-resolver.ts match --path "$file_path" --format json 2>/dev/null || true)"
377
- if [[ -n "$resolver_json" && "$(json_get "$resolver_json" "matched" || true)" == "true" ]]; then
378
- functional_block="$(json_get "$resolver_json" "functional_block")"
379
- capability_id="$(json_get "$resolver_json" "capability_id")"
380
- matched_prefix="$(json_get "$resolver_json" "matched_prefix")"
381
- architecture_domain="$(json_get "$resolver_json" "architecture_domain")"
382
- architecture_capability="$(json_get "$resolver_json" "architecture_capability")"
383
- architecture_module="$(json_get "$resolver_json" "architecture_module")"
384
- workstream_dir="$(json_get "$resolver_json" "workstream_dir")"
385
- contract_agents="$(json_get "$resolver_json" "contract_agents" || true)"
386
- contract_claude="$(json_get "$resolver_json" "contract_claude" || true)"
387
- lsp_profile="$(json_get "$resolver_json" "lsp_profile" || true)"
388
- fi
389
- fi
390
-
391
- matched_prefix="${matched_prefix:-$functional_block}"
392
- capability_id="${capability_id:-$functional_block}"
393
- contract_agents="${contract_agents:-$functional_block/AGENTS.md}"
394
- contract_claude="${contract_claude:-$functional_block/CLAUDE.md}"
395
- lsp_profile="${lsp_profile:-typescript-lsp}"
396
-
397
- if ! validate_block "$functional_block"; then
398
- echo "[ContextContractSync] Root scope or missing functional block; no local AGENTS/CLAUDE contract updated."
399
- exit 0
400
- fi
401
-
402
- mkdir -p "$(dirname "$contract_agents")" "$(dirname "$contract_claude")"
403
-
404
- block_slug="$(safe_token "$functional_block")"
405
- if [[ -z "$architecture_domain" || -z "$architecture_capability" || -z "$architecture_module" || -z "$workstream_dir" ]]; then
406
- derived_scope="$(derive_scope "$functional_block")"
407
- architecture_domain="${architecture_domain:-$(printf '%s\n' "$derived_scope" | sed -n '1p')}"
408
- architecture_capability="${architecture_capability:-$(printf '%s\n' "$derived_scope" | sed -n '2p')}"
409
- architecture_module="${architecture_module:-$(printf '%s\n' "$derived_scope" | sed -n '3p')}"
410
- workstream_dir="${workstream_dir:-$(printf '%s\n' "$derived_scope" | sed -n '4p')}"
411
- fi
412
-
413
- if architecture_event sync-contract-files \
414
- --functional-block "$functional_block" \
415
- --capability-id "$capability_id" \
416
- --matched-prefix "$matched_prefix" \
417
- --architecture-domain "$architecture_domain" \
418
- --architecture-capability "$architecture_capability" \
419
- --architecture-module "$architecture_module" \
420
- --workstream-dir "$workstream_dir" \
421
- --contract-agents "$contract_agents" \
422
- --contract-claude "$contract_claude" \
423
- --event-ts "${event_ts:-unknown}" \
424
- --file-path "${file_path:-unknown}" \
425
- --severity "${severity:-unknown}" \
426
- --change-type "${change_type:-unknown}" \
427
- --request-file "${request_file:-unknown}" \
428
- --lsp-profile "$lsp_profile" 2>/dev/null; then
429
- sync_context_map "$functional_block" "$architecture_domain" "$architecture_capability" "$capability_id" "$contract_agents" "$contract_claude" "$lsp_profile"
430
- echo "[ContextContractSync] Updated $contract_agents and $contract_claude."
431
- exit 0
432
- fi
433
-
434
- latest_snapshot="$({ find docs/architecture/snapshots -type f -name "*${block_slug}*.md" 2>/dev/null || true; } | sort | tail -1)"
435
- latest_human_diagram="$({ find docs/architecture/diagrams -type f -name "*${block_slug}*.html" 2>/dev/null || true; } | sort | tail -1)"
436
- latest_snapshot="${latest_snapshot:-(none yet)}"
437
- latest_human_diagram="${latest_human_diagram:-(none yet)}"
438
- semantic_diagram_source="$architecture_module"
439
- if [[ "$latest_snapshot" != "(none yet)" ]]; then
440
- semantic_diagram_source="$latest_snapshot"
441
- fi
442
- active_workstreams="$(format_active_workstreams "$workstream_dir")"
443
-
444
- block_tmp="$(mktemp)"
445
- cat > "$block_tmp" <<EOF_BLOCK
446
- <!-- BEGIN ARCHITECTURE CONTRACT -->
447
- ## Architecture Contract
448
-
449
- - Functional block: \`${functional_block}\`
450
- - Capability ID: \`${capability_id}\`
451
- - Matched prefix: \`${matched_prefix}\`
452
- - Architecture domain: \`${architecture_domain}\`
453
- - Architecture capability: \`${architecture_capability}\`
454
- - Architecture module: \`${architecture_module}\`
455
- - Last architecture event: ${event_ts:-unknown}
456
- - Last changed path: \`${file_path:-unknown}\`
457
- - Severity: ${severity:-unknown}
458
- - Change type: ${change_type:-unknown}
459
- - Module responsibility: Keep this block aligned with the local boundary described by surrounding human-owned context.
460
- - Entrypoints: \`${functional_block}\`
461
- - Allowed dependencies: Follow root \`AGENTS.md\` / \`CLAUDE.md\` and this local contract.
462
- - Forbidden dependencies: Do not cross sibling app/service/package boundaries without an architecture snapshot or explicit plan.
463
- - Runtime path: \`${functional_block}\`
464
- - LSP/tooling profile: \`${lsp_profile}\`
465
- - Verification: Use root required checks plus local commands recorded in this capability contract.
466
- - Latest snapshot: \`${latest_snapshot}\`
467
- - Semantic diagram source: \`${semantic_diagram_source}\`
468
- - Latest human diagram: \`${latest_human_diagram}\`
469
- - Pending architecture request: \`${request_file:-unknown}\`
470
-
471
- ## Active Workstreams
472
-
473
- ${active_workstreams}
474
-
475
- ## Current Session Projection
476
-
477
- - Durable progress lives under \`${workstream_dir}\`.
478
- - \`tasks/current.md\` is the tracked derived status snapshot; it is not a live lock or task source.
479
- - \`tasks/todos.md\` is the deferred-goal ledger; current execution slices stay in the active plan's \`## Task Breakdown\`.
480
- <!-- END ARCHITECTURE CONTRACT -->
481
- EOF_BLOCK
482
-
483
- base_file=""
484
- if [[ -f "$contract_agents" ]]; then
485
- base_file="$contract_agents"
486
- elif [[ -f "$contract_claude" ]]; then
487
- base_file="$contract_claude"
488
- else
489
- base_file="$(mktemp)"
490
- cat > "$base_file" <<'BASE_EOF'
491
- # Functional Block Agent Context
492
-
493
- Keep this file focused on the local contract for this primary functional block.
494
-
495
- BASE_EOF
496
- fi
497
-
498
- updated_file="$(mktemp)"
499
- if ! replace_contract_block "$base_file" "$updated_file" "$block_tmp"; then
500
- rm -f "$updated_file" "$block_tmp"
501
- if [[ "$base_file" == /tmp/* || "$base_file" == "${TMPDIR:-/tmp}"* ]]; then
502
- rm -f "$base_file"
503
- fi
504
- exit 1
505
- fi
506
-
507
- cp "$updated_file" "$contract_agents"
508
- cp "$updated_file" "$contract_claude"
509
- rm -f "$updated_file" "$block_tmp"
510
- if [[ "$base_file" == /tmp/* || "$base_file" == "${TMPDIR:-/tmp}"* ]]; then
511
- rm -f "$base_file"
512
- fi
513
-
514
- sync_context_map "$functional_block" "$architecture_domain" "$architecture_capability" "$capability_id" "$contract_agents" "$contract_claude" "$lsp_profile"
515
-
516
- echo "[ContextContractSync] Updated $contract_agents and $contract_claude."
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ exec "$SCRIPT_DIR/lib/run-forge-helper.sh" "context-contract-sync.sh" "$@"