@open-agent-toolkit/cli 0.2.72 → 0.2.74

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 (165) hide show
  1. package/assets/agents/oat-reviewer.md +4 -3
  2. package/assets/agents/recon-worker.md +42 -8
  3. package/assets/bundle-metadata.json +1 -1
  4. package/assets/docs/cli-utilities/configuration.md +3 -56
  5. package/assets/docs/cli-utilities/tool-packs.md +4 -4
  6. package/assets/docs/contributing/code.md +2 -2
  7. package/assets/docs/contributing/index.md +0 -1
  8. package/assets/docs/reference/cli-reference.md +1 -1
  9. package/assets/docs/reference/troubleshooting.md +17 -40
  10. package/assets/docs/workflows/projects/artifacts.md +16 -34
  11. package/assets/docs/workflows/projects/lifecycle.md +20 -19
  12. package/assets/docs/workflows/skills/explainer-kit.md +180 -440
  13. package/assets/docs/workflows/skills/index.md +1 -2
  14. package/assets/docs/workflows/skills/recon.md +114 -23
  15. package/assets/public-package-versions.json +4 -4
  16. package/assets/skills/explainer-kit/SKILL.md +96 -171
  17. package/assets/skills/explainer-kit/recipes/engineer-tour.json +1 -22
  18. package/assets/skills/explainer-kit/recipes/program-recap.json +1 -29
  19. package/assets/skills/explainer-kit/recipes/project-explainer.json +1 -22
  20. package/assets/skills/explainer-kit/recipes/project-recap.v2.json +1 -43
  21. package/assets/skills/explainer-kit/references/fact-base-contract.md +76 -101
  22. package/assets/skills/explainer-kit/references/recap-authoring.md +99 -0
  23. package/assets/skills/explainer-kit/schemas/manifest.schema.json +13 -135
  24. package/assets/skills/explainer-kit/scripts/bundle.mjs +712 -0
  25. package/assets/skills/explainer-kit/scripts/lib/claim-subject.mjs +40 -0
  26. package/assets/skills/explainer-kit/scripts/lib/contracts.mjs +113 -1504
  27. package/assets/skills/explainer-kit/scripts/lib/failure.mjs +13 -0
  28. package/assets/skills/explainer-kit/scripts/lib/package-coverage.mjs +57 -403
  29. package/assets/skills/explainer-kit/scripts/lib/qa-result.mjs +168 -0
  30. package/assets/skills/explainer-kit/scripts/lib/qa.mjs +90 -488
  31. package/assets/skills/explainer-kit/scripts/lib/recipes.mjs +28 -545
  32. package/assets/skills/explainer-kit/scripts/lib/run-package.mjs +120 -0
  33. package/assets/skills/explainer-kit/scripts/lib/sanitize.mjs +42 -0
  34. package/assets/skills/explainer-kit/scripts/record.mjs +335 -0
  35. package/assets/skills/explainer-kit/scripts/verify.mjs +648 -0
  36. package/assets/skills/oat-explainer-kit/SKILL.md +57 -117
  37. package/assets/skills/oat-explainer-kit/references/config-contract.md +20 -64
  38. package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +85 -237
  39. package/assets/skills/oat-explainer-kit/scripts/bind-project-sources.mjs +18 -10
  40. package/assets/skills/oat-explainer-kit/scripts/check-core.mjs +1 -0
  41. package/assets/skills/oat-explainer-kit/scripts/check-terminal-outcome.mjs +256 -21
  42. package/assets/skills/oat-explainer-kit/scripts/persist-intent.mjs +82 -3
  43. package/assets/skills/oat-explainer-kit/scripts/resolve-config.mjs +0 -162
  44. package/assets/skills/oat-explainer-kit/scripts/resolve-intent.mjs +57 -123
  45. package/assets/skills/oat-project-autonomous/SKILL.md +14 -13
  46. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +165 -165
  47. package/assets/skills/oat-project-complete/SKILL.md +168 -349
  48. package/assets/skills/oat-project-complete/scripts/consume-persisted-recap-intent.mjs +125 -0
  49. package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +0 -30
  50. package/assets/skills/oat-project-complete/scripts/parse-completion-retry-fields.mjs +4 -37
  51. package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +17 -16
  52. package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +9 -174
  53. package/assets/skills/oat-project-complete/scripts/resolve-completion-retry.mjs +1 -2
  54. package/assets/skills/oat-project-document/SKILL.md +1 -1
  55. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +165 -165
  56. package/assets/skills/oat-project-implement/SKILL.md +1 -1
  57. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +44 -56
  58. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +165 -165
  59. package/assets/skills/oat-project-lite/SKILL.md +1 -1
  60. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +165 -165
  61. package/assets/skills/oat-project-plan/SKILL.md +5 -6
  62. package/assets/skills/oat-project-pr-final/SKILL.md +1 -1
  63. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +165 -165
  64. package/assets/skills/oat-project-quick-start/SKILL.md +1 -1
  65. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +165 -165
  66. package/assets/skills/oat-project-review-receive/SKILL.md +14 -1
  67. package/assets/skills/oat-project-summary/SKILL.md +35 -25
  68. package/assets/skills/oat-wave-execute/SKILL.md +11 -36
  69. package/assets/skills/oat-wave-program/SKILL.md +13 -37
  70. package/assets/skills/recon/SKILL.md +103 -40
  71. package/assets/skills/recon/references/packet-contract.md +150 -67
  72. package/assets/skills/recon/references/profiles.md +38 -16
  73. package/assets/skills/recon/references/worker-contract.md +39 -8
  74. package/assets/skills/recon/scripts/lib/contracts.mjs +703 -55
  75. package/assets/skills/recon/scripts/lib/routing.mjs +588 -0
  76. package/assets/skills/recon/scripts/lib/validated-run.mjs +2 -0
  77. package/assets/skills/recon/scripts/prepare-routing.mjs +88 -0
  78. package/assets/skills/recon/scripts/render-packet.mjs +69 -1
  79. package/assets/skills/recon/scripts/validate-packet.mjs +473 -56
  80. package/assets/skills/subagent-orchestration/SKILL.md +18 -9
  81. package/assets/skills/subagent-orchestration/references/model-selection-principles.md +17 -8
  82. package/dist/commands/config/index.d.ts.map +1 -1
  83. package/dist/commands/config/index.js +9 -113
  84. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  85. package/dist/commands/project/archive/archive-utils.js +32 -184
  86. package/dist/commands/project/archive/explainer-package-coverage.d.ts +3 -8
  87. package/dist/commands/project/archive/explainer-package-coverage.d.ts.map +1 -1
  88. package/dist/commands/project/archive/explainer-package-coverage.js +1 -1
  89. package/dist/config/oat-config.d.ts +0 -11
  90. package/dist/config/oat-config.d.ts.map +1 -1
  91. package/dist/config/oat-config.js +0 -34
  92. package/dist/config/resolve.d.ts.map +1 -1
  93. package/dist/config/resolve.js +0 -8
  94. package/dist/release/public-package-contract.d.ts.map +1 -1
  95. package/dist/release/public-package-contract.js +2 -10
  96. package/dist/validation/project-state.d.ts.map +1 -1
  97. package/dist/validation/project-state.js +42 -3
  98. package/package.json +2 -2
  99. package/assets/docs/contributing/explainer-kit-verification.md +0 -133
  100. package/assets/docs/workflows/skills/explainer-kit-providers.md +0 -155
  101. package/assets/skills/explainer-kit/briefs/deep-dive.md +0 -35
  102. package/assets/skills/explainer-kit/briefs/project-page.md +0 -38
  103. package/assets/skills/explainer-kit/briefs/supporting-diagram.md +0 -28
  104. package/assets/skills/explainer-kit/briefs/walkthrough-deck.md +0 -35
  105. package/assets/skills/explainer-kit/examples/project-explainer/content.md +0 -31
  106. package/assets/skills/explainer-kit/examples/project-explainer/fact-base.md +0 -22
  107. package/assets/skills/explainer-kit/examples/project-recap/content.md +0 -77
  108. package/assets/skills/explainer-kit/examples/project-recap/fact-base.json +0 -104
  109. package/assets/skills/explainer-kit/examples/project-recap/fact-base.md +0 -44
  110. package/assets/skills/explainer-kit/examples/theme-bundle.json +0 -87
  111. package/assets/skills/explainer-kit/recipes/project-recap.v1.json +0 -93
  112. package/assets/skills/explainer-kit/references/contracts.md +0 -324
  113. package/assets/skills/explainer-kit/references/destination-contract.md +0 -210
  114. package/assets/skills/explainer-kit/references/extension-contract.md +0 -80
  115. package/assets/skills/explainer-kit/references/golden-conformance.md +0 -80
  116. package/assets/skills/explainer-kit/references/visual-review.md +0 -71
  117. package/assets/skills/explainer-kit/schemas/author-request.v2.schema.json +0 -212
  118. package/assets/skills/explainer-kit/schemas/author-request.v3.schema.json +0 -241
  119. package/assets/skills/explainer-kit/schemas/author-result.v2.schema.json +0 -52
  120. package/assets/skills/explainer-kit/schemas/build-record.schema.json +0 -98
  121. package/assets/skills/explainer-kit/schemas/durability-evidence.schema.json +0 -53
  122. package/assets/skills/explainer-kit/schemas/publish-receipt.v1.schema.json +0 -97
  123. package/assets/skills/explainer-kit/schemas/publish-receipt.v2.schema.json +0 -215
  124. package/assets/skills/explainer-kit/schemas/publish-request.v1.schema.json +0 -32
  125. package/assets/skills/explainer-kit/schemas/publish-request.v2.schema.json +0 -34
  126. package/assets/skills/explainer-kit/schemas/run-request.schema.json +0 -147
  127. package/assets/skills/explainer-kit/schemas/set-plan.v1.schema.json +0 -149
  128. package/assets/skills/explainer-kit/schemas/terminal-evidence.v1.schema.json +0 -81
  129. package/assets/skills/explainer-kit/schemas/visual-review-evidence.v1.schema.json +0 -66
  130. package/assets/skills/explainer-kit/schemas/visual-review-request.v1.schema.json +0 -117
  131. package/assets/skills/explainer-kit/schemas/visual-review-result.v1.schema.json +0 -80
  132. package/assets/skills/explainer-kit/scripts/lib/catalog.mjs +0 -349
  133. package/assets/skills/explainer-kit/scripts/lib/content-approval.mjs +0 -418
  134. package/assets/skills/explainer-kit/scripts/lib/diagram.mjs +0 -514
  135. package/assets/skills/explainer-kit/scripts/lib/durability.mjs +0 -643
  136. package/assets/skills/explainer-kit/scripts/lib/fact-base.mjs +0 -664
  137. package/assets/skills/explainer-kit/scripts/lib/internal-references.mjs +0 -538
  138. package/assets/skills/explainer-kit/scripts/lib/markdown.mjs +0 -414
  139. package/assets/skills/explainer-kit/scripts/lib/publication-policy.mjs +0 -54
  140. package/assets/skills/explainer-kit/scripts/lib/records.mjs +0 -954
  141. package/assets/skills/explainer-kit/scripts/lib/render.mjs +0 -703
  142. package/assets/skills/explainer-kit/scripts/lib/s3-roots.mjs +0 -353
  143. package/assets/skills/explainer-kit/scripts/lib/s3-static.mjs +0 -759
  144. package/assets/skills/explainer-kit/scripts/lib/set-plan.mjs +0 -209
  145. package/assets/skills/explainer-kit/scripts/lib/source-backlinks.mjs +0 -218
  146. package/assets/skills/explainer-kit/scripts/lib/terminal-evidence.mjs +0 -157
  147. package/assets/skills/explainer-kit/scripts/lib/visual-review.mjs +0 -400
  148. package/assets/skills/explainer-kit/scripts/publish.mjs +0 -76
  149. package/assets/skills/explainer-kit/scripts/record-durability.mjs +0 -64
  150. package/assets/skills/explainer-kit/scripts/render-qa.mjs +0 -461
  151. package/assets/skills/explainer-kit/scripts/run.mjs +0 -3038
  152. package/assets/skills/explainer-kit/scripts/validate.mjs +0 -59
  153. package/assets/skills/oat-explainer-kit/references/author-callback.md +0 -53
  154. package/assets/skills/oat-explainer-kit/references/migration.md +0 -144
  155. package/assets/skills/oat-explainer-kit/references/visual-review-callback.md +0 -83
  156. package/assets/skills/oat-explainer-kit/scripts/derive-destination.mjs +0 -91
  157. package/assets/skills/oat-explainer-kit/scripts/finalize-tracked-run.mjs +0 -531
  158. package/assets/skills/oat-explainer-kit/scripts/probe-recap-seams.mjs +0 -371
  159. package/assets/skills/oat-explainer-kit/scripts/run.mjs +0 -905
  160. package/dist/commands/project/archive/explainer-source-backlinks.d.ts +0 -18
  161. package/dist/commands/project/archive/explainer-source-backlinks.d.ts.map +0 -1
  162. package/dist/commands/project/archive/explainer-source-backlinks.js +0 -27
  163. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts +0 -29
  164. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts.map +0 -1
  165. package/dist/commands/project/archive/explainer-terminal-evidence.js +0 -37
@@ -1,5 +1,3 @@
1
- import { RECAP_PROBE_CODES, RECAP_SEAM_IDS } from './probe-recap-seams.mjs';
2
-
3
1
  const PRODUCTS = new Set(['projectExplainer', 'projectRecap']);
4
2
  const MODES = new Set(['interactive', 'autonomous']);
5
3
  const PREFERENCES = new Set(['always', 'ask', 'never']);
@@ -9,6 +7,7 @@ const SOURCES = new Set([
9
7
  'kickoff_prompt',
10
8
  'autonomous_policy',
11
9
  'capability_probe',
10
+ 'failed_attempt',
12
11
  ]);
13
12
  const ALLOWED_PAIRS = Object.freeze({
14
13
  projectExplainer: new Set([
@@ -21,10 +20,18 @@ const ALLOWED_PAIRS = Object.freeze({
21
20
  'skip:interactive',
22
21
  'generate:autonomous_policy',
23
22
  'skip:capability_probe',
23
+ 'skip:failed_attempt',
24
24
  ]),
25
25
  });
26
26
  const ISO_TIMESTAMP_PATTERN =
27
27
  /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
28
+ const INTENT_RECORD_KEYS = new Set([
29
+ 'decision',
30
+ 'source',
31
+ 'decided_at',
32
+ 'failed_attempt_evidence',
33
+ ]);
34
+ const RUN_SLUG_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
28
35
 
29
36
  export function resolveIntent({
30
37
  product,
@@ -33,7 +40,6 @@ export function resolveIntent({
33
40
  preference,
34
41
  kickoffRequest = false,
35
42
  answer,
36
- seamProbe,
37
43
  now = new Date().toISOString(),
38
44
  }) {
39
45
  assertProduct(product);
@@ -48,20 +54,6 @@ export function resolveIntent({
48
54
  if (typeof kickoffRequest !== 'boolean') {
49
55
  throw new TypeError('kickoffRequest must be a boolean.');
50
56
  }
51
- if (seamProbe !== undefined) {
52
- assertSeamProbe(seamProbe);
53
- if (product !== 'projectRecap') {
54
- throw new Error(
55
- 'Seam probe results apply only to projectRecap resolution.',
56
- );
57
- }
58
- if (mode !== 'autonomous') {
59
- throw new Error(
60
- 'Seam probe results apply only to autonomous projectRecap resolution.',
61
- );
62
- }
63
- }
64
-
65
57
  if (mode === 'autonomous') {
66
58
  if (answer !== undefined) {
67
59
  throw new Error('Autonomous lifecycle intent cannot use an answer.');
@@ -71,7 +63,6 @@ export function resolveIntent({
71
63
  state,
72
64
  preference,
73
65
  kickoffRequest,
74
- seamProbe,
75
66
  now,
76
67
  });
77
68
  }
@@ -130,12 +121,9 @@ export function validateIntentRecord(product, record) {
130
121
  throw new TypeError(`${product} intent must be a decision record.`);
131
122
  }
132
123
  const keys = Object.keys(record);
133
- if (
134
- keys.length !== 3 ||
135
- keys.some((key) => !['decision', 'source', 'decided_at'].includes(key))
136
- ) {
124
+ if (keys.some((key) => !INTENT_RECORD_KEYS.has(key))) {
137
125
  throw new Error(
138
- `${product} intent must contain only decision, source, and decided_at.`,
126
+ `${product} intent contains an unsupported lifecycle decision field.`,
139
127
  );
140
128
  }
141
129
  if (!DECISIONS.has(record.decision)) {
@@ -150,9 +138,54 @@ export function validateIntentRecord(product, record) {
150
138
  );
151
139
  }
152
140
  assertTimestamp(record.decided_at);
141
+ const isFailedAttempt =
142
+ product === 'projectRecap' &&
143
+ record.decision === 'skip' &&
144
+ record.source === 'failed_attempt';
145
+ if (isFailedAttempt) {
146
+ validateFailedAttemptEvidenceLocator(record.failed_attempt_evidence);
147
+ } else if (Object.hasOwn(record, 'failed_attempt_evidence')) {
148
+ throw new Error(
149
+ 'failed_attempt_evidence is allowed only for projectRecap skip/failed_attempt.',
150
+ );
151
+ }
153
152
  return record;
154
153
  }
155
154
 
155
+ export function validateWritableIntentRecord(product, record) {
156
+ validateIntentRecord(product, record);
157
+ if (
158
+ product === 'projectRecap' &&
159
+ record.decision === 'skip' &&
160
+ record.source === 'capability_probe'
161
+ ) {
162
+ throw new Error(
163
+ 'projectRecap skip/capability_probe is a read-only legacy intent.',
164
+ );
165
+ }
166
+ return record;
167
+ }
168
+
169
+ export function validateFailedAttemptEvidenceLocator(value) {
170
+ if (typeof value !== 'string') {
171
+ throw new Error(
172
+ 'projectRecap skip/failed_attempt requires failed_attempt_evidence.',
173
+ );
174
+ }
175
+ const parts = value.split('/');
176
+ if (
177
+ parts.length !== 3 ||
178
+ parts[0] !== 'explainers' ||
179
+ !RUN_SLUG_PATTERN.test(parts[1]) ||
180
+ !['manifest.json', 'failure.json'].includes(parts[2])
181
+ ) {
182
+ throw new Error(
183
+ 'failed_attempt_evidence must be explainers/<run-slug>/manifest.json or explainers/<run-slug>/failure.json.',
184
+ );
185
+ }
186
+ return value;
187
+ }
188
+
156
189
  export function explainerModeForIntent(intent) {
157
190
  if (
158
191
  !intent ||
@@ -172,30 +205,10 @@ function resolveAutonomous({
172
205
  state,
173
206
  preference,
174
207
  kickoffRequest,
175
- seamProbe,
176
208
  now,
177
209
  }) {
178
210
  if (product === 'projectRecap') {
179
211
  const warnings = [];
180
- if (seamProbe !== undefined && seamProbe.ok !== true) {
181
- if (seamProbe.code !== 'seams-unavailable') {
182
- const error = new Error(
183
- `Project recap seams are configured but invalid, so the recap fails closed rather than resolving a capability skip: ${seamProbe.message ?? seamProbe.code}`,
184
- );
185
- error.code = 'E_RECAP_SEAMS_INVALID';
186
- throw error;
187
- }
188
- warnings.push(
189
- `Autonomous project recap skipped: no provider is configured for ${formatSeams(seamProbe.missing)}.`,
190
- );
191
- return result(
192
- product,
193
- 'skip',
194
- 'capability_probe',
195
- createRecord(product, 'skip', 'capability_probe', now),
196
- warnings,
197
- );
198
- }
199
212
  if (state?.decision === 'skip') {
200
213
  warnings.push(
201
214
  'Autonomous project recap policy overrode a lower-precedence skip decision.',
@@ -228,7 +241,7 @@ function resolveAutonomous({
228
241
 
229
242
  function createRecord(product, decision, source, now) {
230
243
  const record = { decision, source, decided_at: now };
231
- validateIntentRecord(product, record);
244
+ validateWritableIntentRecord(product, record);
232
245
  return record;
233
246
  }
234
247
 
@@ -249,85 +262,6 @@ function result(
249
262
  };
250
263
  }
251
264
 
252
- /**
253
- * A seam probe result is a decision input, so a malformed one must fail rather
254
- * than silently degrade into either a skip or a forced generate.
255
- */
256
- function assertSeamProbe(seamProbe) {
257
- if (
258
- !seamProbe ||
259
- typeof seamProbe !== 'object' ||
260
- Array.isArray(seamProbe) ||
261
- typeof seamProbe.ok !== 'boolean' ||
262
- !RECAP_PROBE_CODES.includes(seamProbe.code)
263
- ) {
264
- throw new TypeError(
265
- 'seamProbe must be a probeRecapSeams result with ok and a known code.',
266
- );
267
- }
268
- // A recap that runs from this decision runs unattended, so an interactive
269
- // probe is the wrong evidence: it checks only the author and critic and would
270
- // report a host with no set planner as fully available.
271
- if (seamProbe.mode !== 'unattended') {
272
- throw new TypeError(
273
- 'seamProbe must come from an unattended probe of the recap seams.',
274
- );
275
- }
276
- if (
277
- !Array.isArray(seamProbe.missing) ||
278
- !Array.isArray(seamProbe.invalid) ||
279
- !Array.isArray(seamProbe.resolved)
280
- ) {
281
- throw new TypeError(
282
- 'seamProbe must partition the canonical recap seams into missing, invalid, and resolved.',
283
- );
284
- }
285
- // Enforce the partition this message promises: every canonical seam appears
286
- // in exactly one bucket. Without the disjointness and coverage checks, a
287
- // forged result can claim a seam is both missing and resolved (yielding a
288
- // capability skip the probe would never emit), or pad `resolved` with
289
- // duplicates of one seam to fake full availability and force a generate.
290
- const claimed = [
291
- ...seamProbe.missing,
292
- ...seamProbe.invalid.map((entry) => entry?.seam),
293
- ...seamProbe.resolved,
294
- ];
295
- const distinct = new Set(claimed);
296
- if (
297
- distinct.size !== claimed.length ||
298
- distinct.size !== RECAP_SEAM_IDS.length ||
299
- !RECAP_SEAM_IDS.every((seam) => distinct.has(seam))
300
- ) {
301
- throw new TypeError(
302
- 'seamProbe must partition the canonical recap seams into missing, invalid, and resolved.',
303
- );
304
- }
305
- // The result is a discriminated union, so each code must carry exactly the
306
- // evidence it claims. A half-populated object must never reach the skip
307
- // branch and forge a capability skip out of an invalid seam.
308
- const consistent =
309
- seamProbe.code === 'seams-ok'
310
- ? seamProbe.ok === true &&
311
- seamProbe.missing.length === 0 &&
312
- seamProbe.invalid.length === 0 &&
313
- seamProbe.resolved.length === RECAP_SEAM_IDS.length
314
- : seamProbe.ok === false &&
315
- (seamProbe.code === 'seams-unavailable'
316
- ? seamProbe.missing.length > 0 && seamProbe.invalid.length === 0
317
- : seamProbe.invalid.length > 0);
318
- if (!consistent) {
319
- throw new TypeError(
320
- 'An unsatisfied seamProbe must list the seams its code claims.',
321
- );
322
- }
323
- }
324
-
325
- function formatSeams(seams) {
326
- if (!Array.isArray(seams) || seams.length === 0) return 'a required seam';
327
- if (seams.length === 1) return seams[0];
328
- return `${seams.slice(0, -1).join(', ')} and ${seams.at(-1)}`;
329
- }
330
-
331
265
  function assertProduct(product) {
332
266
  if (!PRODUCTS.has(product)) {
333
267
  throw new Error(`Unsupported lifecycle product: ${String(product)}`);
@@ -6,7 +6,7 @@ disable-model-invocation: true
6
6
  user-invocable: true
7
7
  allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, Task
8
8
  metadata:
9
- version: 1.0.14
9
+ version: 1.0.15
10
10
  ---
11
11
 
12
12
  # Autonomous OAT Project
@@ -264,18 +264,19 @@ existing project is resolved, use the `oat-explainer-kit` lifecycle intent
264
264
  resolver and persistence helper against that project's `state.md`.
265
265
 
266
266
  Resolve and persist `projectRecap` as `generate` with source `autonomous_policy` after project creation or resolution.
267
- Reassert this forced recap intent on resume; a stale lower-precedence skip is overridden, warned, and recorded.
268
- The autonomous mode policy has precedence over project state and workflow
269
- preference, so `never` does not suppress the recap.
270
-
271
- Kickoff persists the forced `generate` intent without probing seams, because the
272
- host that runs the recap is the one that matters and closeout is where it runs.
273
- The closeout recap gate probes seam availability and may resolve a recordable
274
- `skip` with source `capability_probe` on a host where a required seam is
275
- unavailable. That later capability skip is the only thing that overrides this
276
- forced intent, it is decided before any run rather than from a failed one, and
277
- it never blocks unattended completion. Do not reassert `generate` over a
278
- recorded `capability_probe` skip within the same closeout.
267
+ Reassert this forced recap intent on resume unless closeout already persisted
268
+ `skip/failed_attempt`. The autonomous mode policy has precedence over workflow
269
+ preference, so `never` does not suppress the initial recap attempt.
270
+
271
+ Kickoff persists the forced `generate` intent. At closeout, invoke
272
+ `oat-explainer-kit` § Generate with recipe `project-recap`. If the terminal
273
+ outcome is `failed` or `incomplete`, make one retry. If that retry also fails,
274
+ persist `skip/failed_attempt` with `failed_attempt_evidence` naming that run's
275
+ project-relative failed or incomplete `manifest.json`, or its `failure.json`
276
+ when recording did not occur, and continue unattended closeout. On resume, use
277
+ the completion consumer's containment-checked proof and honor that persisted
278
+ skip without another bundle or authoring pass; do not reassert `generate` over
279
+ it.
279
280
 
280
281
  Resolve and persist `projectExplainer` as `generate` with source `kickoff_prompt` only when the kickoff request explicitly asks for a project explainer.
281
282
  A general autonomous goal, project creation, or normal planning does not count as an explainer request.