loopforge 3.9.2 → 4.0.7

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 (285) hide show
  1. package/README.md +236 -112
  2. package/dist/audit.d.ts +73 -15
  3. package/dist/audit.d.ts.map +1 -1
  4. package/dist/audit.js +131 -61
  5. package/dist/audit.js.map +1 -1
  6. package/dist/canonical-state.d.ts +152 -40
  7. package/dist/canonical-state.d.ts.map +1 -1
  8. package/dist/canonical-state.js +382 -206
  9. package/dist/canonical-state.js.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +41 -12
  12. package/dist/cli.js.map +1 -1
  13. package/dist/cognitive-governance.d.ts +0 -2
  14. package/dist/cognitive-governance.d.ts.map +1 -1
  15. package/dist/cognitive-governance.js +0 -4
  16. package/dist/cognitive-governance.js.map +1 -1
  17. package/dist/committed-round.d.ts +105 -141
  18. package/dist/committed-round.d.ts.map +1 -1
  19. package/dist/committed-round.js +249 -372
  20. package/dist/committed-round.js.map +1 -1
  21. package/dist/constraint-lifecycle.d.ts +73 -0
  22. package/dist/constraint-lifecycle.d.ts.map +1 -0
  23. package/dist/constraint-lifecycle.js +174 -0
  24. package/dist/constraint-lifecycle.js.map +1 -0
  25. package/dist/context-boundary.d.ts +83 -0
  26. package/dist/context-boundary.d.ts.map +1 -0
  27. package/dist/context-boundary.js +101 -0
  28. package/dist/context-boundary.js.map +1 -0
  29. package/dist/contract-items.d.ts +12 -8
  30. package/dist/contract-items.d.ts.map +1 -1
  31. package/dist/contract-items.js +31 -26
  32. package/dist/contract-items.js.map +1 -1
  33. package/dist/contract-requirement.d.ts +47 -0
  34. package/dist/contract-requirement.d.ts.map +1 -0
  35. package/dist/contract-requirement.js +51 -0
  36. package/dist/contract-requirement.js.map +1 -0
  37. package/dist/criterion-status.d.ts +35 -0
  38. package/dist/criterion-status.d.ts.map +1 -0
  39. package/dist/criterion-status.js +89 -0
  40. package/dist/criterion-status.js.map +1 -0
  41. package/dist/enforcement-gate.d.ts +32 -67
  42. package/dist/enforcement-gate.d.ts.map +1 -1
  43. package/dist/enforcement-gate.js +203 -439
  44. package/dist/enforcement-gate.js.map +1 -1
  45. package/dist/engine.d.ts +9 -103
  46. package/dist/engine.d.ts.map +1 -1
  47. package/dist/engine.js +28 -887
  48. package/dist/engine.js.map +1 -1
  49. package/dist/errors.d.ts +41 -0
  50. package/dist/errors.d.ts.map +1 -0
  51. package/dist/errors.js +69 -0
  52. package/dist/errors.js.map +1 -0
  53. package/dist/evidence-claims.d.ts +33 -31
  54. package/dist/evidence-claims.d.ts.map +1 -1
  55. package/dist/evidence-claims.js +58 -72
  56. package/dist/evidence-claims.js.map +1 -1
  57. package/dist/evidence-posture-view.d.ts +19 -0
  58. package/dist/evidence-posture-view.d.ts.map +1 -0
  59. package/dist/evidence-posture-view.js +116 -0
  60. package/dist/evidence-posture-view.js.map +1 -0
  61. package/dist/evidence-posture.d.ts +73 -0
  62. package/dist/evidence-posture.d.ts.map +1 -0
  63. package/dist/evidence-posture.js +281 -0
  64. package/dist/evidence-posture.js.map +1 -0
  65. package/dist/evidence-provider.d.ts +55 -37
  66. package/dist/evidence-provider.d.ts.map +1 -1
  67. package/dist/evidence-provider.js +182 -332
  68. package/dist/evidence-provider.js.map +1 -1
  69. package/dist/explain.d.ts +167 -27
  70. package/dist/explain.d.ts.map +1 -1
  71. package/dist/explain.js +373 -58
  72. package/dist/explain.js.map +1 -1
  73. package/dist/field-accounting.d.ts.map +1 -1
  74. package/dist/field-accounting.js +3 -22
  75. package/dist/field-accounting.js.map +1 -1
  76. package/dist/generate-schema.js +13 -8
  77. package/dist/generate-schema.js.map +1 -1
  78. package/dist/git-boundary.d.ts +128 -0
  79. package/dist/git-boundary.d.ts.map +1 -0
  80. package/dist/git-boundary.js +625 -0
  81. package/dist/git-boundary.js.map +1 -0
  82. package/dist/git-facts.d.ts +22 -0
  83. package/dist/git-facts.d.ts.map +1 -0
  84. package/dist/git-facts.js +29 -0
  85. package/dist/git-facts.js.map +1 -0
  86. package/dist/git-motion.d.ts +37 -0
  87. package/dist/git-motion.d.ts.map +1 -0
  88. package/dist/git-motion.js +59 -0
  89. package/dist/git-motion.js.map +1 -0
  90. package/dist/history.d.ts +44 -0
  91. package/dist/history.d.ts.map +1 -0
  92. package/dist/history.js +77 -0
  93. package/dist/history.js.map +1 -0
  94. package/dist/index.d.ts +19 -9
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +12 -4
  97. package/dist/index.js.map +1 -1
  98. package/dist/init.d.ts +16 -0
  99. package/dist/init.d.ts.map +1 -1
  100. package/dist/init.js +80 -14
  101. package/dist/init.js.map +1 -1
  102. package/dist/loop-compiler.d.ts +51 -19
  103. package/dist/loop-compiler.d.ts.map +1 -1
  104. package/dist/loop-compiler.js +423 -507
  105. package/dist/loop-compiler.js.map +1 -1
  106. package/dist/loop-store.d.ts +6 -5
  107. package/dist/loop-store.d.ts.map +1 -1
  108. package/dist/loop-store.js +153 -35
  109. package/dist/loop-store.js.map +1 -1
  110. package/dist/mcp/round-lifecycle.d.ts +285 -81
  111. package/dist/mcp/round-lifecycle.d.ts.map +1 -1
  112. package/dist/mcp/round-lifecycle.js +1629 -574
  113. package/dist/mcp/round-lifecycle.js.map +1 -1
  114. package/dist/mcp/server.d.ts +5 -0
  115. package/dist/mcp/server.d.ts.map +1 -1
  116. package/dist/mcp/server.js +61 -19
  117. package/dist/mcp/server.js.map +1 -1
  118. package/dist/mcp/session.d.ts +81 -39
  119. package/dist/mcp/session.d.ts.map +1 -1
  120. package/dist/mcp/session.js +963 -271
  121. package/dist/mcp/session.js.map +1 -1
  122. package/dist/mcp/submission-boundary.d.ts +23 -31
  123. package/dist/mcp/submission-boundary.d.ts.map +1 -1
  124. package/dist/mcp/submission-boundary.js +242 -82
  125. package/dist/mcp/submission-boundary.js.map +1 -1
  126. package/dist/mcp/submission-handle.d.ts +66 -0
  127. package/dist/mcp/submission-handle.d.ts.map +1 -0
  128. package/dist/mcp/submission-handle.js +173 -0
  129. package/dist/mcp/submission-handle.js.map +1 -0
  130. package/dist/mcp/tools.d.ts +17 -7
  131. package/dist/mcp/tools.d.ts.map +1 -1
  132. package/dist/mcp/tools.js +763 -244
  133. package/dist/mcp/tools.js.map +1 -1
  134. package/dist/open-question.d.ts +7 -0
  135. package/dist/open-question.d.ts.map +1 -0
  136. package/dist/open-question.js +14 -0
  137. package/dist/open-question.js.map +1 -0
  138. package/dist/policy-metrics.d.ts +31 -21
  139. package/dist/policy-metrics.d.ts.map +1 -1
  140. package/dist/policy-metrics.js +117 -64
  141. package/dist/policy-metrics.js.map +1 -1
  142. package/dist/policy.d.ts +15 -40
  143. package/dist/policy.d.ts.map +1 -1
  144. package/dist/policy.js +13 -13
  145. package/dist/policy.js.map +1 -1
  146. package/dist/progress.d.ts +45 -0
  147. package/dist/progress.d.ts.map +1 -0
  148. package/dist/progress.js +136 -0
  149. package/dist/progress.js.map +1 -0
  150. package/dist/prompt-assembler.d.ts +28 -9
  151. package/dist/prompt-assembler.d.ts.map +1 -1
  152. package/dist/prompt-assembler.js +592 -603
  153. package/dist/prompt-assembler.js.map +1 -1
  154. package/dist/prompt-coverage.d.ts +39 -0
  155. package/dist/prompt-coverage.d.ts.map +1 -0
  156. package/dist/prompt-coverage.js +80 -0
  157. package/dist/prompt-coverage.js.map +1 -0
  158. package/dist/prompt-freshness.d.ts +25 -0
  159. package/dist/prompt-freshness.d.ts.map +1 -0
  160. package/dist/prompt-freshness.js +88 -0
  161. package/dist/prompt-freshness.js.map +1 -0
  162. package/dist/prompt-policy.d.ts +14 -4
  163. package/dist/prompt-policy.d.ts.map +1 -1
  164. package/dist/prompt-policy.js +29 -10
  165. package/dist/prompt-policy.js.map +1 -1
  166. package/dist/protocol.d.ts +875 -419
  167. package/dist/protocol.d.ts.map +1 -1
  168. package/dist/protocol.js +73 -99
  169. package/dist/protocol.js.map +1 -1
  170. package/dist/recovery-guidance.d.ts +13 -0
  171. package/dist/recovery-guidance.d.ts.map +1 -0
  172. package/dist/recovery-guidance.js +15 -0
  173. package/dist/recovery-guidance.js.map +1 -0
  174. package/dist/recovery.d.ts +68 -0
  175. package/dist/recovery.d.ts.map +1 -0
  176. package/dist/recovery.js +234 -0
  177. package/dist/recovery.js.map +1 -0
  178. package/dist/replay.d.ts +42 -8
  179. package/dist/replay.d.ts.map +1 -1
  180. package/dist/replay.js +311 -84
  181. package/dist/replay.js.map +1 -1
  182. package/dist/result-facts.d.ts +45 -0
  183. package/dist/result-facts.d.ts.map +1 -0
  184. package/dist/result-facts.js +86 -0
  185. package/dist/result-facts.js.map +1 -0
  186. package/dist/round-contract.d.ts +38 -8
  187. package/dist/round-contract.d.ts.map +1 -1
  188. package/dist/round-contract.js +71 -31
  189. package/dist/round-contract.js.map +1 -1
  190. package/dist/round-coordinator.d.ts +45 -91
  191. package/dist/round-coordinator.d.ts.map +1 -1
  192. package/dist/round-coordinator.js +254 -271
  193. package/dist/round-coordinator.js.map +1 -1
  194. package/dist/round-driver.d.ts +56 -16
  195. package/dist/round-driver.d.ts.map +1 -1
  196. package/dist/round-driver.js +225 -39
  197. package/dist/round-driver.js.map +1 -1
  198. package/dist/round-facts.d.ts +33 -52
  199. package/dist/round-facts.d.ts.map +1 -1
  200. package/dist/round-facts.js +54 -157
  201. package/dist/round-facts.js.map +1 -1
  202. package/dist/round-guidance.d.ts +56 -0
  203. package/dist/round-guidance.d.ts.map +1 -0
  204. package/dist/round-guidance.js +161 -0
  205. package/dist/round-guidance.js.map +1 -0
  206. package/dist/round-outcome.d.ts +21 -0
  207. package/dist/round-outcome.d.ts.map +1 -0
  208. package/dist/round-outcome.js +31 -0
  209. package/dist/round-outcome.js.map +1 -0
  210. package/dist/round-transaction.d.ts +168 -21
  211. package/dist/round-transaction.d.ts.map +1 -1
  212. package/dist/round-transaction.js +856 -39
  213. package/dist/round-transaction.js.map +1 -1
  214. package/dist/self-eval.d.ts +40 -60
  215. package/dist/self-eval.d.ts.map +1 -1
  216. package/dist/self-eval.js +455 -384
  217. package/dist/self-eval.js.map +1 -1
  218. package/dist/storage.d.ts +16 -0
  219. package/dist/storage.d.ts.map +1 -1
  220. package/dist/storage.js +54 -4
  221. package/dist/storage.js.map +1 -1
  222. package/dist/subgoal-state.d.ts +2 -3
  223. package/dist/subgoal-state.d.ts.map +1 -1
  224. package/dist/subgoal-state.js +2 -3
  225. package/dist/subgoal-state.js.map +1 -1
  226. package/dist/submission-guidance.d.ts +43 -21
  227. package/dist/submission-guidance.d.ts.map +1 -1
  228. package/dist/submission-guidance.js +368 -262
  229. package/dist/submission-guidance.js.map +1 -1
  230. package/dist/submission-receipt.d.ts +16 -8
  231. package/dist/submission-receipt.d.ts.map +1 -1
  232. package/dist/submission-receipt.js +146 -51
  233. package/dist/submission-receipt.js.map +1 -1
  234. package/dist/token-utils.d.ts +47 -7
  235. package/dist/token-utils.d.ts.map +1 -1
  236. package/dist/token-utils.js +66 -15
  237. package/dist/token-utils.js.map +1 -1
  238. package/dist/transaction-identity.d.ts +9 -0
  239. package/dist/transaction-identity.d.ts.map +1 -0
  240. package/dist/transaction-identity.js +69 -0
  241. package/dist/transaction-identity.js.map +1 -0
  242. package/dist/verification-actions.d.ts +13 -0
  243. package/dist/verification-actions.d.ts.map +1 -0
  244. package/dist/verification-actions.js +44 -0
  245. package/dist/verification-actions.js.map +1 -0
  246. package/dist/verification-gate.d.ts +26 -46
  247. package/dist/verification-gate.d.ts.map +1 -1
  248. package/dist/verification-gate.js +218 -427
  249. package/dist/verification-gate.js.map +1 -1
  250. package/dist/version.d.ts +1 -1
  251. package/dist/version.js +1 -1
  252. package/dist/working-memory.d.ts +187 -0
  253. package/dist/working-memory.d.ts.map +1 -0
  254. package/dist/working-memory.js +767 -0
  255. package/dist/working-memory.js.map +1 -0
  256. package/dist/workspace-checkpoint.d.ts +88 -0
  257. package/dist/workspace-checkpoint.d.ts.map +1 -0
  258. package/dist/workspace-checkpoint.js +326 -0
  259. package/dist/workspace-checkpoint.js.map +1 -0
  260. package/dist/workspace-restore.d.ts +68 -0
  261. package/dist/workspace-restore.d.ts.map +1 -0
  262. package/dist/workspace-restore.js +604 -0
  263. package/dist/workspace-restore.js.map +1 -0
  264. package/dist/workspace.d.ts +0 -9
  265. package/dist/workspace.d.ts.map +1 -1
  266. package/dist/workspace.js +0 -17
  267. package/dist/workspace.js.map +1 -1
  268. package/loop_policy.json +5 -19
  269. package/package.json +2 -2
  270. package/skills/forge/SKILL.md +212 -0
  271. package/skills/forge/references/evidence-and-contracts.md +204 -0
  272. package/skills/forge/references/recovery-and-views.md +188 -0
  273. package/dist/cognitive-facts.d.ts +0 -30
  274. package/dist/cognitive-facts.d.ts.map +0 -1
  275. package/dist/cognitive-facts.js +0 -113
  276. package/dist/cognitive-facts.js.map +0 -1
  277. package/dist/loop-extras-parser.d.ts +0 -81
  278. package/dist/loop-extras-parser.d.ts.map +0 -1
  279. package/dist/loop-extras-parser.js +0 -213
  280. package/dist/loop-extras-parser.js.map +0 -1
  281. package/dist/loop-projection.d.ts +0 -6
  282. package/dist/loop-projection.d.ts.map +0 -1
  283. package/dist/loop-projection.js +0 -28
  284. package/dist/loop-projection.js.map +0 -1
  285. package/skills/perception/SKILL.md +0 -370
@@ -2,66 +2,71 @@
2
2
  *
3
3
  * All types exchanged between the Main Agent and LoopForge flow through
4
4
  * these interfaces. This is the contract layer — no implementation logic.
5
- *
6
- * v3.3: 41 types — 2 enums + 35 interfaces + 4 type aliases.
5
+ * The generated JSON Schema in `loopforge-protocol.json` is the complete,
6
+ * machine-readable wire contract; `$defs` is the authoritative type set.
7
7
  */
8
- export declare enum Mode {
9
- LOOP_COMPILE = "loop_compile",
10
- FEEDBACK = "feedback"
11
- }
12
8
  export declare enum AgentStatus {
13
9
  OK = "ok",
14
10
  ERROR = "error",
15
11
  STALLED = "stalled"
16
12
  }
17
- export interface ExecutionFeedback {
18
- output: string;
19
- success: boolean;
20
- constraint_violations: string[];
21
- manual_fixes_needed: string;
22
- }
23
- export declare function makeExecutionFeedback(overrides?: Partial<ExecutionFeedback>): ExecutionFeedback;
24
- /** P5: A revision to a success criterion — the old form and the new form.
25
- * The agent proposes this when it discovers the original criterion was
26
- * wrong, unrealistic, or needs refinement. */
27
- export interface CriterionRevision {
28
- old: string;
29
- new: string;
30
- }
31
13
  /** Structured self-evaluation submitted at the round boundary.
32
14
  * The agent outputs this after completing each round.
33
15
  * Every field is consumed by at least one downstream function.
34
16
  *
35
17
  * v1.4 (P0–P2): Three new optional fields enable cognitive evolution.
36
- * v1.5 (P4–P5): Execution evidence, progress tracking, and self-correction. */
18
+ * v1.5 (P4–P5): Execution evidence, progress tracking, and self-correction.
19
+ *
20
+ * v4.0.6: `outcome` is the ONE round conclusion (it replaces `success` and
21
+ * `agent_stop_reason`); `execution_report.claims` is the ONE claims channel
22
+ * (it replaces `criterion_claims` + `contract_item_claims`); `round_contract`
23
+ * is the ONE contract channel (an optional `supersedes` modifier replaces
24
+ * `contract_transition`). The required field set is still exactly four:
25
+ * `outcome`, `output_summary`, `constraint_violations`, `should_continue`.
26
+ *
27
+ * Optional fields are normalized leniently and never dropped silently: the
28
+ * normalizer returns stable diagnostics for every correction, and a committed
29
+ * transaction persists them with the submitted-field manifest. Two fields are
30
+ * structural exceptions validated BEFORE the round advances —
31
+ * `subgoal_updates` and `round_contract` (including its `supersedes` and the
32
+ * `rci-` entries of `execution_report.claims`) — because each references the
33
+ * exact derived set the Agent was shown. `scope` is deliberately not
34
+ * structural: optional, report-only intent, normalized leniently and never
35
+ * rejected.
36
+ *
37
+ * `objective_refinement` evolves the OVERALL starting objective (the working
38
+ * version of `OperatorAcceptance.task`), not the current round's slice. It is
39
+ * event-driven and never changes criteria or hard constraints. */
37
40
  export interface SelfEvaluation {
38
- /** true ONLY if all hard constraints were met and the task goal was achieved. */
39
- success: boolean;
41
+ /** The ONE round conclusion. `success` requires `should_continue=false`;
42
+ * `blocked` requires `should_continue=false` and a non-empty `blocker`;
43
+ * `partial` and `failed` may continue or stop. */
44
+ outcome: RoundOutcome;
40
45
  /** Specific, actionable summary of what was DONE this round.
41
- * Feeds: buildRollingSummary (key_outcomes),
42
- * computeConstraintRetirement (activity detection), vault lineage. */
46
+ * Feeds: committed record, state file, audit/replay/explain, backtrack
47
+ * facts, and the BOUNDED fresh-prompt Working Memory. It is always an
48
+ * Agent report — never machine evidence, never current governance, and
49
+ * never an independent history. */
43
50
  output_summary: string;
44
51
  /** Constraints the agent actually violated this round.
45
52
  * Feeds: deriveRecurringFlags (the constraint_violation kind) and
46
53
  * computeConstraintRetirement. */
47
54
  constraint_violations: string[];
48
- /** false ONLY when the entire task is complete. Tells the autonomous
49
- * runner to stop the loop. Not consumed by the compiler. */
55
+ /** The Agent's logical round-boundary decision: false stops the loop after
56
+ * this accepted round; true asks the runner to prepare a successor round.
57
+ * A Round Contract scopes that successor's work and acceptance conditions,
58
+ * but does not decide whether this round ends. `maxRounds` remains the
59
+ * runner's hard stop. */
50
60
  should_continue: boolean;
51
61
  /** P0: New constraints discovered during this round that were not
52
62
  * known before. Merged into the active constraint set by the compiler.
53
63
  * Omit or leave empty if none discovered. */
54
64
  discovered_constraints?: string[];
55
- /** P1: A refinement / deepening of the task objective based on this
56
- * round's discoveries. Appended to (never replaces) the original
57
- * objective. Omit if understanding is unchanged. */
58
- objective_refinement?: string;
59
- /** P2: Sub-problems that surfaced during execution and may need
60
- * separate attention. Feed into the next-task suggestion.
61
- * Omit or leave empty if none emerged.
62
- * v3.7.1: this is the ONLY creation channel. A text matching the
63
- * sg-XXXXXXXX ID pattern is rejected — creation never accepts an
64
- * ID reference (that would fabricate a phantom hashed item). */
65
+ /** Sub-problems that surfaced during execution. This is the ONLY
66
+ * sub-goal creation channel; the runtime derives stable sg- ids and tracks
67
+ * their lifecycle. Omit or leave empty if none emerged.
68
+ * v3.7.1: a text matching the sg-XXXXXXXX ID pattern is rejected —
69
+ * creation never accepts an ID reference. */
65
70
  emerged_subtasks?: string[];
66
71
  /** v3.7.1: Explicit status transitions for EXISTING sub-goals. Each
67
72
  * entry must reference a committed sub-goal ID (sg-XXXXXXXX) and a
@@ -78,37 +83,45 @@ export interface SelfEvaluation {
78
83
  * Removed from the active constraint set by the compiler.
79
84
  * Omit or leave empty if none. */
80
85
  retracted_constraints?: string[];
81
- /** P5: Success criteria that need revision. The agent discovered the
82
- * original criterion was incorrect and proposes a new formulation.
83
- * Applied to the Loop Objective by the compiler (version++). */
84
- revised_success_criteria?: CriterionRevision[];
85
- /** P5: Assumptions the agent made in earlier rounds that turned out to
86
- * be wrong. Recorded in the rolling summary as key lessons.
87
- * Omit or leave empty if none. */
86
+ /** Assumptions the agent made in earlier rounds that turned out to be
87
+ * wrong. A committed Agent report; it surfaces in bounded Working Memory
88
+ * and recovery brief facts, never as a LoopForge conclusion or machine
89
+ * evidence. Omit or leave empty if none. */
88
90
  wrong_assumptions?: string[];
89
- /** v1.10: Agent declares a subtask boundary. When true, the compiler
90
- * generates an agent_declared milestone. */
91
- compression_checkpoint?: boolean;
92
- /** v1.10: Human-readable label for this checkpoint (e.g. "数据模型层完成").
93
- * Used as the checkpoint heading in subsequent prompts. */
94
- checkpoint_label?: string;
91
+ /** v4.0.2: unresolved questions that still affect later slices. Strictly
92
+ * report-only: it feeds Working Memory, replay and explain, never the
93
+ * verification gate, success, contract closure or machine evidence.
94
+ * At most 3 entries, 300 chars each. It is a question list, not a todo
95
+ * list and not a completion checklist. */
96
+ open_questions?: string[];
97
+ /** v4.0.2: stable ids of questions resolved in this round. IDs are derived
98
+ * from normalized open-question text and are report-only. */
99
+ resolved_open_question_ids?: string[];
100
+ /** v4.0.3 (renamed from compression_checkpoint): the Agent declares a
101
+ * subtask boundary. When true, the next compile uses an L2 rehydration
102
+ * boundary; no milestone or phase narrative is generated. It is not a
103
+ * workspace checkpoint. */
104
+ subtask_boundary?: boolean;
105
+ /** v4.0.3 (renamed from checkpoint_label): a label stored on the committed
106
+ * report. It does not create a later prompt heading and is not a real
107
+ * checkpoint reference. */
108
+ subtask_boundary_label?: string;
95
109
  /** Multi-agent: Results of sub-agent / Worker delegations this round.
96
- * The main agent (or Coordinator) reports what it delegated.
97
- * The engine automatically writes these to the delegation journal.
98
- * Omit or leave empty if no delegations occurred. */
110
+ * The main agent reports what it delegated; the report is saved inside the
111
+ * committed transaction for audit. Omit or leave empty if none occurred. */
99
112
  worker_results?: WorkerResult[];
100
- /** v2.5: Why the agent is stopping. Only meaningful when
101
- * should_continue=false and success=false. Defaults to "gave_up"
102
- * (current behavior) when absent. "blocked" means work cannot proceed
103
- * under current constraints; "needs_human_input" requires intervention. */
104
- stop_reason?: "gave_up" | "blocked" | "needs_human_input";
105
- /** v2.12: Declared outcome (four values). When absent, derived from success
106
- * (true → "success", false → "failed"). "partial" and "blocked" can only
107
- * be declared explicitly. A declared non-success outcome suppresses the
108
- * success-class verification checks even when success=true. */
109
- outcome?: RoundOutcome;
110
- /** v2.12: Flat blocker description, meaningful only when outcome==="blocked".
111
- * Also feeds the user/agent gate classification (P2). ≤ 500 chars. */
113
+ /** v4.0.6: the Agent's working version of the OVERALL starting objective
114
+ * (`OperatorAcceptance.task`). When present, the latest committed
115
+ * refinement on the current branch replaces the working objective used by
116
+ * the next prompt and goalId. It never rewrites Operator Acceptance,
117
+ * success criteria or hard constraints, and it is not the round task or
118
+ * contract. Event-driven: omit when the overall objective is unchanged.
119
+ * Strict at the submission boundary: string, trim non-empty, ≤ 1000 chars. */
120
+ objective_refinement?: string;
121
+ /** v2.12 / v4.0.6: Flat blocker description, required when
122
+ * outcome==="blocked" (trim non-empty, ≤ 500 chars). When another outcome
123
+ * is declared it is dropped with a diagnostic and never rejects the round.
124
+ * Also feeds the user/agent gate classification (P2). */
112
125
  blocker?: string;
113
126
  /** v2.12: Retroactive claims that a PRIOR round satisfied a criterion.
114
127
  * The runtime verifies these against the prior round's git evidence.
@@ -130,76 +143,161 @@ export interface SelfEvaluation {
130
143
  * the round is rejected. Safe pre-work (investigation, dry-runs,
131
144
  * rollback evidence) never needs a gate. */
132
145
  gate_ids?: string[];
133
- /** Model's information needs for the next round's prompt.
134
- * Consumed by the Compiler — not durable across rounds. */
135
- prompt_requests?: PromptRequests;
136
- /** v3.3: Round Contract. v3.4: a PROPOSAL for the NEXT round's contract
137
- * (restated unchanged while the current one is active; a new one after
138
- * it completes or blocks). Becomes the ACTIVE contract only once this
139
- * round commits; it is then derived at compile time from committed
140
- * rounds — see round-contract.ts. Optional. */
146
+ /** v3.3/v4.0.6: THE Round Contract channel. A PROPOSAL for the NEXT
147
+ * round's contract. Omit it to continue the active contract unchanged;
148
+ * declare it to start the next slice; add the optional `supersedes`
149
+ * modifier to replace an active contract that is no longer the right
150
+ * slice. Becomes the ACTIVE contract only once this round commits; it is
151
+ * then derived at compile time from committed rounds — see
152
+ * round-contract.ts. With contract capability, a continuing round that has
153
+ * a successor available must leave an active contract for the next round;
154
+ * the final configured round has no successor consumer. */
141
155
  round_contract?: RoundContractProposal;
142
156
  }
143
- /** v2.12: Tri-state round outcome. Declared via SelfEvaluation.outcome;
144
- * derived from `success` when absent. Shared by the dual gates, the stop
145
- * mapping, and the audit view. */
146
- export type RoundOutcome = "success" | "partial" | "failed" | "blocked";
147
- /** v2.12: Typed cognitive state projection — runtime-derived facts shipped
148
- * with advance/status outputs. All fields are derived, zero persistence.
149
- * Consumers: advance output (main agent), status (human/tooling), resume
150
- * handoff. The runtime provides facts; the agent decides actions. */
151
- export interface LoopProjection {
152
- /** Current focus — last non-failed round's output summary. */
153
- focus: {
154
- what: string;
155
- since_round: number;
156
- } | null;
157
- /** Suggested next steps, derived from the active contract, sub-goals, and
158
- * open gates/recovery requirements. Non-authoritative. v3.8: the
159
- * `agent_intent` source was deleted with `next_action` — the agent's own
160
- * plan is no longer a projection input. */
161
- todo: Array<{
162
- id: string;
163
- item: string;
164
- reason: string;
165
- source: "derived";
166
- priority: number;
167
- }>;
168
- /** Phase boundaries from milestone history. */
169
- phase: {
170
- current: string;
171
- label: string;
172
- boundaries: Array<{
173
- label: string;
174
- round: number;
175
- }>;
176
- } | null;
177
- /** Record view of the main agent's reported delegation state — facts
178
- * only, never a task book for sub-agents. */
179
- delegation: {
180
- pending: number;
181
- last_results: Array<{
182
- agentId: string;
183
- outcome: string;
184
- round: number;
185
- summary: string;
186
- }>;
187
- };
188
- /** Handoff capsule for resume / process handover. `verified` holds
189
- * cr-IDs backed by the P0 provenance layer. */
190
- handoff: {
191
- summary: string;
192
- verified: string[];
193
- open_risks: string[];
194
- };
195
- /** v3.8: Sub-goals a machine-verified contract item backs. The machine's
196
- * separate statement about a `done` sub-goal — it never rewrites
197
- * `SubGoal.status`. Derived in cognitive-facts.ts, exposed here so the
198
- * projection carries the same verification view the prompt and state file
199
- * do. */
200
- verified_subgoals: VerifiedSubGoalFact[];
157
+ /** v3.9.7: the kind of recovery material a checkpoint represents. `before` is
158
+ * the automatic transaction before-image; `mid` is an Agent-created savepoint
159
+ * during a round. Both are evidence/recovery material, never progress. */
160
+ export type CheckpointRole = "before" | "mid";
161
+ /** v3.9.7: a checkpoint reference held by a typed transaction snapshot. This
162
+ * reference is the authority for ownership, current-branch visibility and the
163
+ * redo round. The manifest alone is content-addressed recovery material and
164
+ * can never become a recovery point by itself. */
165
+ export interface CheckpointRef {
166
+ checkpointId: string;
167
+ contentHash: string;
168
+ role: CheckpointRole;
169
+ /** Logical round whose snapshot carries this reference. */
170
+ round: number;
171
+ roundId: string;
172
+ /** Transaction that currently owns this reference (retry may re-bind it). */
173
+ transactionId: string;
174
+ branchId: string;
175
+ /** First round of the child branch if this checkpoint is restored. For
176
+ * before/mid checkpoints this equals `round`. */
177
+ redoRound: number;
178
+ createdAt: number;
179
+ }
180
+ /** v4.0.0: the ONE transport projection of the held round attempt.
181
+ *
182
+ * It bundles the three identities a held-round call needs — the owning
183
+ * session, the logical round, and the exact transaction attempt — so a client
184
+ * copies one object instead of three independent strings. It is DERIVED from
185
+ * the persisted session snapshot on every response; it is never persisted in
186
+ * the session document, a round transaction, a prompt artifact, guidance, or
187
+ * a receipt.
188
+ *
189
+ * It is not a security token and grants no authority: the session lease plus
190
+ * an exact comparison against the held snapshot remain the only authority. A
191
+ * stale handle never submits work; a live session re-anchors through
192
+ * `loopforge_status`, and a lost prompt or missing live session is recovered
193
+ * through `loopforge_resume`. */
194
+ export interface SubmissionHandle {
195
+ sessionId: string;
196
+ roundId: string;
197
+ transactionId: string;
198
+ }
199
+ /** v4.0.3: the checkpoint manifest version. The wire type, the store and the
200
+ * restore preflight all read this ONE constant. */
201
+ export declare const CHECKPOINT_SCHEMA_VERSION: 1;
202
+ /** v3.9.7: the restore-relevant content manifest. `fingerprints` is exactly
203
+ * the Git observation boundary; `contents` names the dirty regular files and
204
+ * symlinks whose bytes are stored as content-addressed blobs. */
205
+ export interface WorkspaceCheckpointManifest {
206
+ schemaVersion: typeof CHECKPOINT_SCHEMA_VERSION;
207
+ checkpointId: string;
208
+ loopId: string;
209
+ round: number;
210
+ role: CheckpointRole;
211
+ createdAt: number;
212
+ head?: string;
213
+ dirty: string[];
214
+ fingerprints: Record<string, string>;
215
+ contents: string[];
216
+ coverage: "tracked_and_non_ignored_untracked";
217
+ contentHash: string;
218
+ }
219
+ /** v3.9.7: The Agent's request to abandon the current branch and restore a
220
+ * checkpoint it selected. This is an ACTION, not an evaluation: it never
221
+ * carries success/output_summary/constraint_violations/should_continue and
222
+ * never fabricates a SelfEvaluation. The checkpoint must be visible in the
223
+ * current held transaction or a committed evaluation transaction on the
224
+ * current branch. LoopForge records the directive, executes and verifies the
225
+ * restore, and only then issues the redo prompt. The reason is the Agent's
226
+ * judgment, recorded verbatim and never judged. */
227
+ export interface RecoveryRequest {
228
+ target_checkpoint_id: string;
229
+ reason: string;
201
230
  }
202
- export declare function makeLoopProjection(overrides?: Partial<LoopProjection>): LoopProjection;
231
+ /** v3.9.6: The operator-owned acceptance surface, written once in the root
232
+ * branch's round-1 evaluation transaction. Neither the Agent nor LoopForge
233
+ * may revise, replace, or retract it. */
234
+ export interface OperatorAcceptance {
235
+ task: string;
236
+ success_criteria: string[];
237
+ hard_constraints: string[];
238
+ }
239
+ /** v3.9.7: the committed recovery target. It references a checkpoint by id and
240
+ * content hash; the manifest is the one copy of the boundary. `redo_round`
241
+ * is the branch fence: parent rounds with `round < redo_round` are retained,
242
+ * and the child branch starts at `redo_round`. */
243
+ export interface RecoveryTarget {
244
+ checkpoint_id: string;
245
+ content_hash: string;
246
+ role: CheckpointRole;
247
+ /** Round that owns the checkpoint reference. */
248
+ round: number;
249
+ round_id: string;
250
+ /** Transaction that owns the checkpoint reference. */
251
+ transaction_id: string;
252
+ /** First round of the child branch. */
253
+ redo_round: number;
254
+ }
255
+ /** v4.0.1: the compile facts stamped into an evaluation transaction at commit.
256
+ * They are the machine-computed state the next compile carries forward, not
257
+ * Agent input. `task`/`goalId` serve level and replay; the constraint sets
258
+ * are the effective compile result. */
259
+ export interface CompiledRoundFacts {
260
+ task: string;
261
+ goalId: string;
262
+ constraintsActive: string[];
263
+ constraintsRetired: string[];
264
+ }
265
+ /** v3.9.7: A committed rollback directive. It is a typed event in the same
266
+ * round document as the abandoned/triggering transaction, not a normal
267
+ * round. `transaction_id` also names the child branch; the redo and all
268
+ * later transactions on that branch carry it as `branchId`.
269
+ *
270
+ * The directive deliberately does NOT duplicate the target's HEAD or
271
+ * fingerprints: the checkpoint manifest is the one copy, bound by
272
+ * `target.content_hash`. `skipped_files` is a report fact derived from the
273
+ * target manifest vs. the abandoned boundaries; it is never a restore gate. */
274
+ export interface RecoveryDirective {
275
+ origin: "agent" | "machine";
276
+ /** Agent reason or machine failure reason. */
277
+ reason: string;
278
+ /** Machine check id; never set for an agent request. */
279
+ trigger_rule?: string;
280
+ target: RecoveryTarget;
281
+ skipped_files: string[];
282
+ /** v4.0.3: machine-observed vs Agent-reported abandoned files. */
283
+ observed_skipped_files?: string[];
284
+ reported_skipped_files?: string[];
285
+ /** v4.0.3: every committed round abandoned by the directive. */
286
+ abandoned_rounds?: number[];
287
+ skipped_discoveries: string[];
288
+ failed_rounds: number[];
289
+ /** v4.0.3: compact trigger findings replayed into the redo's Verification
290
+ * Gate (machine backtrack). Never inferred on an agent directive. */
291
+ trigger_findings?: VerificationFlag[];
292
+ /** Committed Agent reports from abandoned rounds. */
293
+ approaches: string[];
294
+ wrong_assumptions: string[];
295
+ /** The directive transaction; also the child branch identity. */
296
+ transaction_id: string;
297
+ }
298
+ /** v2.12 / v4.0.6: the ONE round outcome, required on every evaluation.
299
+ * Shared by the dual gates, the stop mapping, and every read view. */
300
+ export type RoundOutcome = "success" | "partial" | "failed" | "blocked";
203
301
  /** v2.12: Structured high-risk action descriptor (internal — audit display
204
302
  * and gate classification). The MCP surface uses a flat gate text instead. */
205
303
  export interface GateActionDescriptor {
@@ -233,23 +331,6 @@ export interface GateDecision {
233
331
  actionHash: string;
234
332
  }
235
333
  export declare function makeGateDecision(overrides?: Partial<GateDecision>): GateDecision;
236
- /** v2.9: Model-expressed information needs for the next round.
237
- * Submitted via SelfEvaluation.prompt_requests, consumed by the
238
- * Compiler when assembling the next prompt. Transient — each round's
239
- * requests apply to that round only. */
240
- export interface PromptRequests {
241
- /** Items to emphasize. Matched against active state by stable id or
242
- * normalized-exact text (v3.8.1 — the Jaccard arm is gone). Matching items
243
- * are pulled into a "Critical Context" section rendered before optional
244
- * sections. No content is added — only reordered. An unmatched entry is
245
- * dropped. Max entries: policy-driven (L2: 5, L1: 3). L0: ignored. */
246
- emphasize?: string[];
247
- /** Things the model is confused about. Rendered at the prompt top
248
- * as "Confusion Alerts" before the Objective section. Compiler
249
- * auto-matches each entry against state sections and provides
250
- * pointers. Max 3 entries, each ≤ 200 chars. L0: ignored. */
251
- confusion_points?: string[];
252
- }
253
334
  /** v3.9.1: One normalization diagnostic. The submission boundary NEVER drops
254
335
  * an optional value silently: every drop, truncation or normalization is
255
336
  * reported with a stable code and an actionable detail. Strict boundary
@@ -294,6 +375,33 @@ export interface SubmissionReceipt {
294
375
  * a committed record but NOT the submitted evaluation applied. */
295
376
  record: "committed" | "rollback_directive" | "none";
296
377
  entered_history: boolean;
378
+ /** v4.0.3/v4.0.6: the Agent's success claim — a derived projection of
379
+ * `outcome === "success"`, never an input field. */
380
+ agent_success_claim: boolean;
381
+ /** v4.0.6: the Agent-declared outcome. */
382
+ agent_outcome: RoundOutcome | null;
383
+ /** v4.0.6: the Agent's working objective refinement carried by this
384
+ * submission, verbatim; null means the working objective was unchanged. */
385
+ objective_refinement: string | null;
386
+ /** v4.0.4: the LoopForge terminal reason, when this submission stopped the
387
+ * loop. Derived read-view from the SAME `result.stopReason` that Explain,
388
+ * Replay and resume read; never persisted in the receipt and never
389
+ * re-derived from the Agent's outcome or the evidence posture. */
390
+ loop_stop_reason: StopReason | null;
391
+ /** v3.9.7: the checkpoint this submission was judged against. Present only
392
+ * when a pending rollback directive governed the submission — the redo.
393
+ * `restore_verified` reads the redo transaction's verified-restore marker;
394
+ * the directive itself remains the committed audit record. This is the
395
+ * redo's receipt projection of it, never a second ledger. */
396
+ recovery_checkpoint?: {
397
+ checkpoint_id: string;
398
+ redo_round: number;
399
+ origin: "agent" | "machine";
400
+ reason: string;
401
+ /** Machine result: the redo snapshot carries a restore marker produced by
402
+ * the verified restore. The directive remains the committed audit record. */
403
+ restore_verified: boolean;
404
+ };
297
405
  reports: Array<{
298
406
  path: string;
299
407
  handling: SubmissionReportHandling;
@@ -305,6 +413,12 @@ export interface SubmissionReceipt {
305
413
  after_id: string | null;
306
414
  activated: boolean;
307
415
  closed: boolean;
416
+ /** v3.9.9/v4.0.6: the ACTIVE contract closed by this round's explicit
417
+ * `round_contract.supersedes` (report-only fact, derived from the
418
+ * committed redirect — never inferred from `contract_premature`). */
419
+ superseded?: boolean;
420
+ /** v3.9.9/v4.0.6: the Agent's redirect reason, verbatim (report-only). */
421
+ redirect_reason?: string;
308
422
  };
309
423
  subgoals_created: Array<{
310
424
  id: string;
@@ -316,35 +430,51 @@ export interface SubmissionReceipt {
316
430
  to: string;
317
431
  }>;
318
432
  constraints_declared: string[];
433
+ /** Effective retractions only, from the next compile's retired set. */
319
434
  constraints_retracted: string[];
435
+ /** "observed" only when a next compile exists; never guess. */
436
+ constraints_retraction: "observed" | "not_observed";
437
+ /** Requests that resolved to no effective retraction. */
438
+ constraints_not_retracted: string[];
320
439
  /** "observed" only when a next compile (or the next committed round's
321
440
  * stamped active set) exists; "not_observed" for stop/terminate/reject/
322
441
  * backtrack. Never guess an active set from the agent's report. */
323
442
  constraints_activation: "observed" | "not_observed";
324
443
  constraints_active_after: string[] | null;
325
444
  constraints_not_expanded: string[];
326
- checkpoint: {
445
+ subtask_boundary: {
327
446
  label: string;
328
447
  round: number;
329
448
  } | null;
330
449
  rollback: {
331
- restore_point: number;
450
+ redo_round: number;
451
+ target_checkpoint_id: string;
332
452
  preserved_discoveries: string[];
333
453
  wrong_assumptions: string[];
454
+ /** v4.0.3: machine-observed vs Agent-reported abandoned files. */
455
+ observed_skipped_files: string[];
456
+ reported_skipped_files: string[];
457
+ abandoned_rounds: number[];
458
+ /** Stable finding ids that triggered a machine backtrack. */
459
+ trigger_finding_ids: string[];
460
+ origin?: "agent" | "machine";
461
+ reason?: string;
334
462
  } | null;
335
463
  };
336
464
  verification: {
337
- /** Contract-item posture (RoundVerificationStatus). */
338
- contract_status: "trusted" | "insufficient" | "contradicted";
339
- /** Round-level machine evidence posture. A round can have trusted
340
- * contract items while a bare success claim has no machine evidence. */
341
- evidence_status: "verified" | "unavailable" | "absent";
465
+ /** v4.0.3: the ONE persisted evidence posture of this submission. It
466
+ * replaces the former `contract_status` + `evidence_status` pair, which
467
+ * could disagree about the same round. */
468
+ evidence_posture: EvidencePosture;
342
469
  checks: Array<{
343
470
  field: string;
344
471
  check: string;
345
472
  severity: string;
346
473
  detail: string;
474
+ /** v3.9.4: the concrete subject (command id, path, or stable id). */
475
+ ref?: string;
347
476
  }>;
477
+ /** Read from the same posture snapshot. */
348
478
  contract_items: Array<{
349
479
  item_id: string;
350
480
  status: ContractItemStatus;
@@ -355,28 +485,29 @@ export interface SubmissionReceipt {
355
485
  prompt: {
356
486
  level: "l0" | "l1" | "l2";
357
487
  dropped_sections: string[];
358
- prompt_request_effects: PromptRequestEffect[];
488
+ /** v4.0.2: the context boundary the NEXT prompt was compiled under, read
489
+ * from the same PromptArtifact that produced it. Absent only when no next
490
+ * artifact exists (terminal/rejected-without-retry paths). */
491
+ context_mode?: PromptContextMode;
492
+ context_reason?: PromptContextReason;
493
+ /** v4.0.5: the host instruction this prompt carried, projected from the
494
+ * same artifact. null means none was provided for that invocation. */
495
+ current_user_instruction?: string | null;
359
496
  } | null;
360
497
  diagnostics: SubmissionDiagnostic[];
361
498
  }
362
- /** v3.9.1: What a prompt request actually did in the rendered prompt. This is
363
- * an OUTPUT fact about the current render; it is never an instruction for a
364
- * later prompt. */
365
- export interface PromptRequestEffect {
366
- field: "emphasize" | "confusion_points";
367
- request: string;
368
- status: "applied" | "no_match" | "level_ignored" | "capped";
369
- }
370
499
  /** v3.9.1: The live submission-guidance projection returned with a prepared
371
500
  * round. It is derived from current facts only (committed rounds, policy,
372
501
  * the compiled state); it is never persisted and never becomes input to a
373
502
  * later prompt. Real ids are rendered only when the facts exist; a null
374
503
  * example means "not usable at this submission point". */
375
504
  export interface SubmissionGuidance {
376
- round_id: string;
377
505
  active_contract: {
378
506
  id: string;
379
507
  work_item?: string;
508
+ /** v3.9.9: the Agent's declared intent boundary. Report-only — it is not
509
+ * enforced and never rejects a round. */
510
+ scope: string[];
380
511
  declared_at_round: number;
381
512
  items: Array<{
382
513
  id: string;
@@ -387,24 +518,46 @@ export interface SubmissionGuidance {
387
518
  } | null;
388
519
  contract_commands: string[];
389
520
  contract_verification_available: boolean;
521
+ /** v4.0.6: the compiled-time contract coverage requirement. A DERIVED
522
+ * projection of current facts through `deriveContractRequirement`; it is
523
+ * not a new fact and owns no state. */
524
+ contract_requirement: {
525
+ /** If you continue and LoopForge permits a successor round, that round
526
+ * must have an active contract when verification capability exists. */
527
+ required_on_continue: boolean;
528
+ /** The active contract is still open: closing it this round AND
529
+ * continuing requires a successor proposal. */
530
+ successor_required_if_closed: boolean;
531
+ reason: "no_active_contract" | "active_contract_continues" | "active_contract_closed" | "no_contract_capability" | "no_successor_round";
532
+ active_contract_id: string | null;
533
+ };
390
534
  subgoals: Array<{
391
535
  id: string;
392
536
  description: string;
393
537
  status: string;
394
538
  }>;
395
- /** Current real criteria, for criterion_claims selection/examples. */
539
+ /** Current real criteria, for `execution_report.claims` selection/examples. */
396
540
  criteria: Array<{
397
541
  id: string;
398
542
  text: string;
399
- status: CriterionStatus["status"];
543
+ /** The same closed status set as `CriterionStatus.status`, written inline
544
+ * so the generated JSON Schema publishes the enum instead of an
545
+ * unrepresentable indexed-access placeholder. */
546
+ status: "unknown" | "claimed" | "remaining" | "insufficient" | "contradicted" | "verified";
400
547
  }>;
401
548
  recovery: {
402
- required: boolean;
403
- restore_point?: number;
404
- target_head?: string;
549
+ /** The directive is pending until the redo round commits. */
550
+ pending: boolean;
551
+ redo_round: number;
552
+ checkpoint_id: string;
553
+ /** True after the executor verified the restored boundary. */
554
+ restore_verified: boolean;
555
+ origin?: "agent" | "machine";
556
+ reason?: string;
405
557
  } | null;
406
558
  prompt: {
407
- level: "l0" | "l1" | "l2";
559
+ /** null when no prompt artifact is observable; never guess a level. */
560
+ level: "l0" | "l1" | "l2" | null;
408
561
  dropped_sections: string[];
409
562
  protected_overflow: boolean;
410
563
  };
@@ -419,40 +572,10 @@ export interface SubmissionGuidance {
419
572
  check: string;
420
573
  severity: string;
421
574
  detail: string;
575
+ /** v3.9.4: the concrete subject (command id, path, or stable id). */
576
+ ref?: string;
422
577
  }>;
423
578
  }
424
- /** v2.1: Milestone summary — a phase-boundary snapshot that survives
425
- * rolling-window eviction. Triggered by three signals in priority order:
426
- *
427
- * 1. agent_declared — compression_checkpoint === true (agent marks phase complete)
428
- * 2. criteria_milestone — a new met criterion_claim detected (semantic dedup)
429
- * 3. auto — safety net after N rounds without a milestone
430
- *
431
- * Built from raw round data in vault entries — no new persistent storage.
432
- * Rendered in L2 prompts and always written to the state file. */
433
- export interface MilestoneSummary {
434
- /** Human-readable label. Examples:
435
- * agent_declared: agent's checkpoint_label or "Round 15"
436
- * criteria_milestone: "Completed: unit tests ≥ 90%"
437
- * auto: "Rounds 1–20" */
438
- label: string;
439
- /** Which rounds this milestone covers (inclusive). */
440
- round_range: {
441
- start: number;
442
- end: number;
443
- };
444
- /** Compressed outcome: what was accomplished in this phase. */
445
- outcome: string;
446
- /** Constraints that were active when this milestone was created. */
447
- carried_constraints: string[];
448
- /** Constraints resolved during this phase. */
449
- resolved_constraints: string[];
450
- /** How this milestone was created. */
451
- kind: "agent_declared" | "criteria_milestone" | "auto";
452
- /** The round number when this milestone was created. */
453
- generated_at_round: number;
454
- }
455
- export declare function makeMilestoneSummary(overrides?: Partial<MilestoneSummary>): MilestoneSummary;
456
579
  /** A single sub-agent / Worker delegation result (v1.9 — multi-agent).
457
580
  * v3.7.1: `outcome` is the single reported fact. `success` is deleted —
458
581
  * entries without a valid outcome are dropped by the parser, never
@@ -461,34 +584,21 @@ export declare function makeMilestoneSummary(overrides?: Partial<MilestoneSummar
461
584
  * is always accepted. */
462
585
  export interface WorkerResult {
463
586
  agentId: string;
464
- subAgentType?: string;
465
587
  subTask: string;
466
588
  resultSummary: string;
467
589
  outcome: "success" | "partial" | "failed";
468
- discoveredConstraints?: string[];
469
590
  }
470
591
  export declare function makeSelfEvaluation(overrides?: Partial<SelfEvaluation>): SelfEvaluation;
471
- /** Regex to extract a self-evaluation JSON block from agent output. */
472
- export interface LoopForgeRequest {
473
- task: string;
474
- mode: Mode;
475
- feedback: ExecutionFeedback | null;
476
- skill_name: string | null;
477
- task_id: string | null;
478
- [key: string]: unknown;
479
- }
480
592
  export interface LoopObjective {
593
+ /** v4.0.6: the WORKING objective — the latest committed
594
+ * `objective_refinement` on the current branch, else the operator
595
+ * acceptance task. Criteria and hard constraints always come from the
596
+ * immutable `OperatorAcceptance`; a refinement only changes this text. */
481
597
  objective: string;
482
598
  success_criteria: string[];
483
599
  hard_constraints: string[];
484
600
  created_at_round: number;
485
601
  loop_id: string;
486
- /** P1: Version number for the objective, starting at 1.
487
- * Incremented each time objective_refinement is applied. */
488
- version?: number;
489
- /** P1: Ordered history of all objective refinements applied.
490
- * Each entry is the refinement text from a single round. */
491
- refinement_history?: string[];
492
602
  }
493
603
  /** v3.2: Derived per-criterion status for the progress dashboard — the
494
604
  * "goal → criteria → evidence" vertical view. Zero persistence: derived
@@ -504,11 +614,14 @@ export interface CriterionStatus {
504
614
  /** The criterion text as declared in the objective. */
505
615
  text: string;
506
616
  status: "unknown" | "claimed" | "remaining" | "insufficient" | "contradicted" | "verified";
507
- /** Round when the criterion was first reported met (machine-backed). */
508
- met_at_round?: number;
509
- /** Sub-goals an item referencing this criterion also names, via explicit
510
- * `subgoal_refs` (v3.8.1 — never a text-similarity guess). */
511
- related_subgoal_ids: string[];
617
+ /** v4.0.3: the round the CURRENT status was first reached. For an Agent
618
+ * claim it is the latest claim round (latest-claim wins); for a machine
619
+ * fact it is the round that reached that machine status. Absent for
620
+ * `unknown`. */
621
+ status_at_round?: number;
622
+ /** v4.0.3: who produced the current status. `agent` for claimed/remaining;
623
+ * `machine` for verified/insufficient/contradicted; absent for unknown. */
624
+ status_source?: "agent" | "machine";
512
625
  }
513
626
  /** v3.2: A deterministic "lesson learned" — a constraint or verification
514
627
  * check that failed repeatedly across rounds. Rendered in the prompt to
@@ -537,23 +650,9 @@ export interface RecurringFlag {
537
650
  rounds: number[];
538
651
  }
539
652
  export declare function makeLoopObjective(overrides?: Partial<LoopObjective>): LoopObjective;
540
- export interface RollingSummary {
541
- /** v1.12: Unified key outcomes — merged from what_worked + key_lessons.
542
- * Format: "[R{round}] ✓/✗ ({technique}): {summary}" */
543
- key_outcomes: string[];
544
- rounds_sampled: number;
545
- generated_at_round: number;
546
- /** v1.7: Detected failure patterns — repeated failed rounds with
547
- * the same technique and similar task text. These are surfaced as
548
- * explicit warnings in the prompt. */
549
- failed_patterns?: string[];
550
- /** v2.1: Phase-boundary milestone summaries that survive rolling-window
551
- * eviction. Accumulated across all rounds from three trigger signals
552
- * (agent_declared > criteria_milestone > auto). Rendered in L2 prompts
553
- * and always written to the state file. */
554
- milestones?: MilestoneSummary[];
555
- }
556
- export declare function makeRollingSummary(overrides?: Partial<RollingSummary>): RollingSummary;
653
+ /** The operator acceptance carried by a committed transaction is the same
654
+ * immutable surface the compiler used to derive the objective. */
655
+ export declare function operatorAcceptanceFromObjective(objective: LoopObjective): OperatorAcceptance;
557
656
  /** v3.7.1: One explicit sub-goal status transition. The closed migration
558
657
  * matrix (loop-compiler.ts, single source) governs legality:
559
658
  * in_progress from pending|blocked; done from pending|in_progress|blocked;
@@ -607,20 +706,28 @@ export interface ConstraintMeta {
607
706
  /** Which round this constraint was last violated by the agent.
608
707
  * 0 if never violated. */
609
708
  last_violated_at_round: number;
610
- /** Origin — criteria texts carry the cr-XXXXXXXX namespace (v3.3.1). */
611
- source: "hard" | "plan" | "criteria" | "discovered";
709
+ /** Origin — criteria texts carry the cr-XXXXXXXX namespace (v3.3.1).
710
+ * `discovered`/`preserved` are Agent declarations, never machine facts;
711
+ * `unrecorded` means committed facts cannot establish an origin. */
712
+ source: "hard" | "plan" | "criteria" | "discovered" | "preserved" | "unrecorded";
713
+ /** First committed round of the current active provenance, when derivable.
714
+ * Absent (never 0) when the origin round cannot be established from
715
+ * committed facts. */
716
+ source_round?: number;
612
717
  }
613
718
  export declare function makeConstraintMeta(overrides?: Partial<ConstraintMeta>): ConstraintMeta;
614
719
  export interface LoopRoundResult {
615
720
  round: number;
616
- success: boolean;
721
+ /** v4.0.3: the Agent's success claim — a derived read projection of
722
+ * `outcome === "success"`, never an input field. */
723
+ agentSuccessClaim: boolean;
724
+ /** v4.0.6: the Agent-declared outcome. Always present on an evaluation;
725
+ * rollback directives use `RoundProcessResult.agentOutcome = null`. */
726
+ agentOutcome: RoundOutcome;
617
727
  output_summary: string;
618
728
  constraint_violations: string[];
619
- manual_fixes_needed: string;
620
729
  /** P0: Constraints discovered during this round. */
621
730
  discovered_constraints?: string[];
622
- /** P1: Objective refinement from this round. */
623
- objective_refinement?: string;
624
731
  /** P2: Sub-problems that emerged during this round. */
625
732
  emerged_subtasks?: string[];
626
733
  /** v3.7.1: Explicit sub-goal transitions declared this round.
@@ -630,22 +737,19 @@ export interface LoopRoundResult {
630
737
  execution_report?: ExecutionReport;
631
738
  /** P5: Constraints retracted this round. */
632
739
  retracted_constraints?: string[];
633
- /** P5: Success criteria revised this round. */
634
- revised_success_criteria?: CriterionRevision[];
635
740
  /** P5: Wrong assumptions identified this round. */
636
741
  wrong_assumptions?: string[];
742
+ /** v4.0.2: unresolved questions reported this round (report-only). */
743
+ open_questions?: string[];
744
+ /** v4.0.2: stable ids of questions resolved this round (report-only). */
745
+ resolved_open_question_ids?: string[];
637
746
  /** Multi-agent: Delegation results from this round.
638
747
  * Set from SelfEvaluation.worker_results during buildLoopRequest. */
639
748
  worker_results?: WorkerResult[];
640
- /** v1.10: Agent declared a subtask boundary in this round. */
641
- compression_checkpoint?: boolean;
642
- /** v1.10: Human-readable label for the checkpoint. */
643
- checkpoint_label?: string;
644
- /** Model's information needs for the next round's prompt.
645
- * Carried forward from SelfEvaluation. Consumed by the Compiler. */
646
- prompt_requests?: PromptRequests;
647
- /** v2.12: Declared outcome. Carried forward from SelfEvaluation. */
648
- outcome?: RoundOutcome;
749
+ /** v4.0.3: Agent declared a subtask boundary in this round. */
750
+ subtask_boundary?: boolean;
751
+ /** v4.0.3: Human-readable label for the subtask boundary. */
752
+ subtask_boundary_label?: string;
649
753
  /** v2.12: Flat blocker description (outcome==="blocked" only). */
650
754
  blocker?: string;
651
755
  /** v2.12: Retroactive claims against prior rounds. */
@@ -659,21 +763,33 @@ export interface LoopRoundResult {
659
763
  }
660
764
  export declare function makeLoopRoundResult(overrides?: Partial<LoopRoundResult>): LoopRoundResult;
661
765
  export interface LoopCompileRequest {
662
- mode: Mode;
663
766
  loop_id: string;
664
767
  round: number;
665
- goal_id: string;
768
+ /** The LOOP's task text for this compile. `goal_id` is no longer a request
769
+ * input: v4.0.6 derives it from the WORKING objective (the latest committed
770
+ * `objective_refinement`, else Operator Acceptance), so a refinement
771
+ * changes goal identity.
772
+ *
773
+ * v4.0.5: this is the LOOP's task. It participates in density and state
774
+ * hashing. The latest host-provided user input for this invocation is
775
+ * `current_user_instruction`, which never changes `task`. */
666
776
  task: string;
667
- domain: string;
668
- next_task_proposal: string;
777
+ /** v4.0.5: the host's explicit user instruction for THIS invocation,
778
+ * already trimmed by the transport boundary. It is invocation input, not
779
+ * loop identity: it never rewrites `task`, the objective, criteria, hard
780
+ * constraints, the Round Contract or goal identity. It projects into
781
+ * `CanonicalLoopState.currentUserInstruction` and the prompt/artifact; it
782
+ * is not evaluation input, not Working Memory and not a gate fact. */
783
+ current_user_instruction?: string;
784
+ /** v4.0.5: set only by the held-attempt recompile path when the host
785
+ * declares the original invocation is gone (`invocationLost`). It selects
786
+ * `fresh_invocation / invocation_recovery` and L2 density for the SAME
787
+ * logical round/attempt. Not an Agent evaluation, not machine evidence. */
788
+ invocation_recovery?: boolean;
669
789
  loop_objective: LoopObjective | null;
670
790
  plan_source: string | null;
671
791
  constraints_from_plan: string[];
672
- new_since_last_round: string;
673
- last_round_result: LoopRoundResult | null;
674
792
  force_level: string;
675
- /** Optional context supplied explicitly by the embedding Agent. */
676
- external_context?: string;
677
793
  /** Maximum rounds for this loop. Used by the state file header to show
678
794
  * accurate progress (Round X / Y). */
679
795
  max_rounds?: number;
@@ -681,25 +797,208 @@ export interface LoopCompileRequest {
681
797
  * these to select a rehydrate view and render the gate findings exactly
682
798
  * once as part of the final prompt. */
683
799
  verification_flags?: VerificationFlag[];
684
- /** One-based attempt within the same logical round. Enforcement rejection
685
- * increments this without advancing `round`. */
800
+ /** One-based submission-attempt number within the same logical round. Only
801
+ * an enforcement rejection increments it (payload errors such as
802
+ * `evaluation_invalid`/`contract_invalid` do not change attempt or the
803
+ * handle). It does not advance `round`. */
686
804
  attempt: number;
687
805
  /** Consecutive zero-commit enforcement rejections for this round. */
688
806
  consecutive_rejections: number;
689
807
  /** Structured enforcement feedback rendered into retry prompts. */
690
808
  rejection_notice: string;
809
+ /** v4.0.3: the rejected attempt's transient evidence posture. Rendered only
810
+ * for a clean-context retry (`attempt > 1`,
811
+ * `contextMode === "fresh_invocation"`); it is never committed history,
812
+ * never Working Memory and never a gate input. */
813
+ retry_evidence_posture?: EvidencePosture;
814
+ /** v4.0.3: compile-context fact — this prompt was compiled after a verified
815
+ * restore of the pending directive. Never Agent input, never persisted. */
816
+ restore_verified?: boolean;
691
817
  }
692
818
  export declare function makeLoopCompileRequest(overrides?: Partial<LoopCompileRequest>): LoopCompileRequest;
819
+ /** v3.9.4: ID-level proof that the current prompt rendered every active
820
+ * normative object. This is an OUTPUT fact about one render — never an
821
+ * instruction for a later prompt and never an input to fact derivation.
822
+ *
823
+ * `active` is the required set derived from the same `CanonicalLoopState`
824
+ * the renderer consumed; `rendered` is the union of the IDs the included
825
+ * sections declared; `omitted = active - rendered`. `complete` is false only
826
+ * when a normative ID was lost; prompt preparation then fails closed.
827
+ *
828
+ * Ordering is deterministic: `active` by (kind rank, id), `rendered` sorted
829
+ * unique, `omitted` by id. */
830
+ export interface PromptCoverage {
831
+ active: Array<{
832
+ id: string;
833
+ kind: "constraint" | "criterion" | "contract" | "contract_item" | "subgoal" | "finding" | "recovery";
834
+ }>;
835
+ rendered: string[];
836
+ omitted: Array<{
837
+ id: string;
838
+ /** Every normative section is protected, so a normative omission can
839
+ * only be a renderer defect. Keeping a single reason prevents a defect
840
+ * from being disguised as a level/budget decision. */
841
+ reason: "defect";
842
+ }>;
843
+ complete: boolean;
844
+ }
693
845
  /** Immutable record of the exact prompt delivered for one round attempt. */
694
- /** v3.8.1: the artifact schema version, next to the type it versions. The
695
- * transaction envelope parser reads it, so the constant lives here rather
696
- * than in the renderer. */
697
- export declare const PROMPT_ARTIFACT_SCHEMA_VERSION: 3;
846
+ /** v4.0.2 / v4.0.4: the context boundary of one prompt delivery.
847
+ *
848
+ * `fresh_invocation` means CLEAN CONTEXT: the host starts a NEW MODEL
849
+ * CONVERSATION with only this prompt, the loop/session identity and the
850
+ * committed/derived facts it carries; the previous transcript, tool logs and
851
+ * uncommitted reasoning are NOT part of it. A clean context is not a new
852
+ * loop and not a workspace reset: the loopId and the current modified
853
+ * workspace continue. It may describe the SAME logical round (a rejection
854
+ * escalation or recovered retry) or the next logical round after the last
855
+ * commit. Read `contextReason` and `attempt`
856
+ * together; a fresh invocation alone does not mean a new round.
857
+ *
858
+ * What `fresh_invocation` clears is MODEL CONVERSATION STATE — the previous
859
+ * transcript, tool outputs and uncommitted reasoning. It does NOT require
860
+ * the host to restart its process, MCP connection, tool services, installed
861
+ * skill files or workspace; a host process that stays alive may keep those
862
+ * warm, and it holds the submissionHandle for this invocation's tool calls.
863
+ * A warm runtime is not model memory: the new conversation knows only what
864
+ * this prompt and the host's stable environment provide. LoopForge does not
865
+ * manage provider prompt/KV caches or implicit Agent habits and neither
866
+ * clears nor relies on them. Only committed facts and the bounded
867
+ * projections LoopForge returns for this invocation are guaranteed;
868
+ * anything else that must survive belongs to explicit host configuration,
869
+ * not a second LoopForge fact source.
870
+ *
871
+ * The legal `fresh_invocation` reasons are `first_round`, `next_round`,
872
+ * `recovery_redo`, `rejection_escalation` and `invocation_recovery`;
873
+ * `enforcement_retry` belongs only to `same_round_retry`. The one prose
874
+ * source for the host contract is `HOST_INVOCATION_CONTRACT` in
875
+ * `round-guidance.ts`.
876
+ *
877
+ * `same_round_retry` means IN-CONTEXT REPAIR: a retry below the repeated
878
+ * rejection escalation threshold. Prompt density is independent: an L0/L1/L2
879
+ * prompt can continue the original invocation when it is still alive. The
880
+ * host injects the rejection notice and Verification Gate findings. If the
881
+ * invocation is gone, the host must call
882
+ * `loopforge_resume(loopId, invocationLost: true)`: LoopForge recompiles the
883
+ * SAME logical round and attempt as `fresh_invocation / invocation_recovery`
884
+ * instead of reusing this in-context prompt.
885
+ *
886
+ * `rejection_escalation` means the same enforcement check has been rejected
887
+ * repeatedly. The host starts a new invocation to break a potentially
888
+ * unproductive reasoning trajectory, while the same logical round and
889
+ * modified workspace continue. The rejected posture is an observation of
890
+ * that attempt, not a snapshot of the current workspace; inspect the current
891
+ * workspace before acting.
892
+ *
893
+ * `invocation_recovery` means the host declared the original invocation
894
+ * lost. It is a clean context for the SAME logical round/attempt, compiled
895
+ * from the held retry facts; the host never starts a new round or attempt.
896
+ *
897
+ * The value is DERIVED by the compiler from compile inputs and committed
898
+ * facts. It is never submitted by the Agent and never re-derived by the MCP
899
+ * lifecycle; every response projects it from the committed PromptArtifact. */
900
+ export type PromptContextMode = "fresh_invocation" | "same_round_retry";
901
+ /** Why the compiler selected the context boundary. It explains the selection;
902
+ * it does not replace the contextStrategy label (`clean context`,
903
+ * `in-context repair`, `clean context after restore`, `clean context
904
+ * repair`). Repeated same-check rejection escalation has its own reason,
905
+ * including when the current round is a recovered redo with a Recovery Brief.
906
+ * `invocation_recovery` is the cold-context replacement of an in-context
907
+ * retry whose invocation disappeared. */
908
+ export type PromptContextReason = "first_round" | "next_round" | "recovery_redo" | "enforcement_retry" | "rejection_escalation" | "invocation_recovery";
909
+ /** v4.0.5: the ONE runtime whitelist for context modes. The types above stay
910
+ * explicit string unions (the schema generator reads them); these arrays are
911
+ * the runtime legality boundary shared by the transaction decoder,
912
+ * committed-history validation and the MCP output schema. */
913
+ export declare const PROMPT_CONTEXT_MODES: readonly ["fresh_invocation", "same_round_retry"];
914
+ /** v4.0.5: the ONE runtime whitelist for context reasons. See
915
+ * `PROMPT_CONTEXT_MODES`. */
916
+ export declare const PROMPT_CONTEXT_REASONS: readonly ["first_round", "next_round", "recovery_redo", "enforcement_retry", "rejection_escalation", "invocation_recovery"];
917
+ export declare function isPromptContextMode(value: unknown): value is PromptContextMode;
918
+ export declare function isPromptContextReason(value: unknown): value is PromptContextReason;
919
+ /** v4.0.3: how many committed items existed BEFORE any cap/dedupe. It is
920
+ * derived once by Working Memory and travels through canonical state (and
921
+ * therefore stateHash); renderers compare it with the rendered counts so an
922
+ * omission is always visible. */
923
+ export interface WorkingMemorySourceCounts {
924
+ /** Committed rounds in the fixed recent window. */
925
+ windowRounds: number;
926
+ reports: number;
927
+ assumptions: number;
928
+ openQuestions: number;
929
+ recoveries: number;
930
+ redirects: number;
931
+ }
932
+ /** v4.0.2/v4.0.3: what the prompt projection actually rendered from the
933
+ * bounded Working Memory. Audit metadata only — it never feeds a decision.
934
+ * `rendered: false` means the section was dropped whole (allowPartial=false)
935
+ * or no prompt section exists; `sourceCounts` still states what existed. */
936
+ export interface PromptWorkingMemoryProjection {
937
+ /** v4.0.3: whether the section body actually entered this prompt. */
938
+ rendered: boolean;
939
+ /** Report rounds actually rendered, newest first. */
940
+ reportRounds: number[];
941
+ /** Rendered per-category counts. */
942
+ counts: {
943
+ reports: number;
944
+ assumptions: number;
945
+ openQuestions: number;
946
+ recoveries: number;
947
+ redirects: number;
948
+ };
949
+ /** Pre-cap, pre-dedupe committed counts. */
950
+ sourceCounts: WorkingMemorySourceCounts;
951
+ /** sourceCounts minus rendered counts, per category. */
952
+ omittedCounts: {
953
+ reports: number;
954
+ assumptions: number;
955
+ openQuestions: number;
956
+ recoveries: number;
957
+ redirects: number;
958
+ };
959
+ /** Stable `oq-` ids actually rendered. */
960
+ questionIds: string[];
961
+ /** The latest report's projection facts; null when none was rendered. */
962
+ previousReport: {
963
+ round: number;
964
+ sourceChars: number;
965
+ renderedChars: number;
966
+ truncated: boolean;
967
+ } | null;
968
+ /** Characters the Working Memory section body produced. */
969
+ renderedChars: number;
970
+ /** True when a window, list/item cap, text limit or budget rule omitted any
971
+ * content, including details within a rendered recovery. Per-recovery
972
+ * source/rendered/omitted detail counts are stated in that item's body;
973
+ * `omittedCounts.recoveries` counts whole recovery records only. */
974
+ truncated: boolean;
975
+ }
976
+ /** v3.8.1: the artifact schema version lives next to the type it versions.
977
+ * The transaction envelope parser reads it, so the constant lives here rather
978
+ * than in the renderer.
979
+ *
980
+ * v4.0.1: schema 7 removes the prompt-request effects. v4.0.2: schema 8 adds
981
+ * the derived context boundary and the optional Working Memory projection.
982
+ * v4.0.3: schema 9 adds the expanded Working Memory audit metadata. The
983
+ * Machine Evidence projection is rendered INTO the prompt text, not carried as
984
+ * a separate artifact field; the committed posture lives on the transaction
985
+ * result. v4.0.4: schema 10 renames the clean-context `contextMode` value to
986
+ * `fresh_invocation`. v4.0.5: schema 11 is ADDITIVELY extended — it adds the
987
+ * optional `currentUserInstruction` fact and the legal
988
+ * `invocation_recovery` reason. No required field was removed or renamed, so
989
+ * every 4.0.4 artifact still decodes; the shared decoder whitelists
990
+ * (`PROMPT_CONTEXT_MODES` / `PROMPT_CONTEXT_REASONS`) are the only legality
991
+ * boundary.
992
+ *
993
+ * v4.0.6: schema 12 is a BREAKING shape break — the evaluation block renders
994
+ * `outcome` plus one `execution_report.claims` channel and the contract
995
+ * coverage requirement, and the old `success` / `agent_stop_reason` /
996
+ * `contract_transition` / `tests_reported` paths are gone. Older artifacts
997
+ * are a HARD break — a round whose artifact does not parse is not committed
998
+ * history, and `legacyTransactionRounds` reports the loss rather than letting
999
+ * it vanish. There is no migration. */
1000
+ export declare const PROMPT_ARTIFACT_SCHEMA_VERSION: 12;
698
1001
  export interface PromptArtifact {
699
- /** v3.9.1: schema 3 adds prompt-request render effects. Older versions are
700
- * a HARD break — a round whose artifact does not parse is not committed
701
- * history, and `legacyTransactionRounds` reports the loss rather than
702
- * letting it vanish. */
703
1002
  schemaVersion: typeof PROMPT_ARTIFACT_SCHEMA_VERSION;
704
1003
  /** Round identity: `loop:<loopId>:round:<n>`. */
705
1004
  roundId: string;
@@ -707,6 +1006,10 @@ export interface PromptArtifact {
707
1006
  round: number;
708
1007
  attempt: number;
709
1008
  level: "l0" | "l1" | "l2";
1009
+ /** The context boundary of THIS delivery: a new model conversation or an
1010
+ * in-context retry. It is not a host/tool restart; see PromptContextMode. */
1011
+ contextMode: PromptContextMode;
1012
+ contextReason: PromptContextReason;
710
1013
  renderedPrompt: string;
711
1014
  promptHash: string;
712
1015
  stateHash: string;
@@ -722,28 +1025,39 @@ export interface PromptArtifact {
722
1025
  * budgeting because it is never dropped. Measured over the SAME region as
723
1026
  * `renderedChars`. */
724
1027
  budget: number;
725
- /** Characters the budgeted region produced: the fixed header, the confusion
726
- * alerts and the rendered sections — everything except the footer. NOT the
727
- * full prompt length; `renderedPrompt` adds the footer on top. */
1028
+ /** Characters the budgeted region produced: the fixed header and the
1029
+ * rendered sections — everything except the footer. NOT the full prompt
1030
+ * length; `renderedPrompt` adds the footer on top. */
728
1031
  renderedChars: number;
729
- /** v3.9.1: what the PREVIOUS round's prompt_requests did in this render.
730
- * OUTPUT ONLY — no compile or decision path may read it as control state. */
731
- promptRequestEffects?: PromptRequestEffect[];
1032
+ /** v3.9.4: ID-level proof that every active normative object was rendered.
1033
+ * Required: a schema-4 artifact without it is a hard break. */
1034
+ coverage: PromptCoverage;
1035
+ /** v3.9.6: compile diagnostics delivered with this exact prompt. Replaces
1036
+ * the session-only `currentWarnings` mirror, so a held prompt remains
1037
+ * self-contained across a restart. */
1038
+ warnings?: string[];
1039
+ /** v4.0.2: present only when this prompt rendered bounded Working Memory.
1040
+ * Audit metadata; it is not a second history and is never an input to a
1041
+ * later prompt. */
1042
+ workingMemory?: PromptWorkingMemoryProjection;
1043
+ /** v4.0.5: the trimmed host-provided user instruction THIS prompt carried,
1044
+ * even when prompt de-duplication rendered no separate section. It is an
1045
+ * audit fact about the invocation, not committed governance: it never
1046
+ * becomes an objective/criterion/constraint/contract, never enters
1047
+ * `CompiledRoundFacts`, Working Memory or a gate, and read views project it
1048
+ * from here instead of keeping a second copy. */
1049
+ currentUserInstruction?: string;
732
1050
  }
733
1051
  export interface LoopCompileResponse {
734
1052
  status: AgentStatus;
735
1053
  prompt: string;
736
1054
  recompile_level: string;
737
- diff_from_previous: string;
738
- lineage: string[];
739
1055
  constraints_active: string[];
740
1056
  constraints_retired: string[];
741
1057
  loop_id: string;
742
1058
  round: number;
743
1059
  goal_id: string;
744
- goal_text_hash: string;
745
1060
  loop_objective: LoopObjective | null;
746
- rolling_summary: RollingSummary | null;
747
1061
  /** v2.2: Structured sub-goals tracked across rounds. Compiler-managed
748
1062
  * lifecycle with derived status. Rendered as Sub-Goal Dashboard. */
749
1063
  sub_goals?: SubGoal[];
@@ -772,54 +1086,23 @@ export interface LoopCompileResponse {
772
1086
  state_file_content?: string;
773
1087
  /** Exact, hashed prompt record used by transaction replay and audit. */
774
1088
  prompt_artifact?: PromptArtifact;
1089
+ /** v4.0.1: the compile facts the transaction stamps at commit. */
1090
+ compiled?: CompiledRoundFacts;
1091
+ /** v4.0.1: the immutable operator surface this compile used. */
1092
+ operatorAcceptance?: OperatorAcceptance;
775
1093
  }
776
1094
  export declare function makeLoopCompileResponse(overrides?: Partial<LoopCompileResponse>): LoopCompileResponse;
777
- /** Aggregated evidence snapshot for the state file Evidence section.
778
- * Four categories give the agent a clear picture of what's been confirmed,
779
- * what remains, what was wrong, and what's newly discovered — all derived
780
- * from accumulated SelfEvaluation data across rounds. */
781
- export interface EvidenceSnapshot {
782
- /** Criteria met + successful outcomes confirmed across rounds. */
783
- verified: string[];
784
- /** Criteria still unmet — work remaining. */
785
- pending: string[];
786
- /** Wrong assumptions + retracted constraints — things we were wrong about. */
787
- invalidated: string[];
788
- /** New constraints + emerged subtasks discovered this round. */
789
- discovered: string[];
790
- }
791
- export declare function makeEvidenceSnapshot(overrides?: Partial<EvidenceSnapshot>): EvidenceSnapshot;
792
- export interface LoopForgeResponse {
793
- status: AgentStatus;
794
- prompt: string | null;
795
- error: string | null;
796
- /** v1.14: State file content from the compiler. Written to disk by the caller. */
797
- state_file_content?: string;
798
- /** Exact prompt artifact produced by the compiler. */
799
- prompt_artifact?: PromptArtifact;
800
- /** Structured warnings from the compiler — preferred over parsing prompt text. */
801
- warnings?: string[];
802
- /** v2.12: Compiler-derived state passed through for typed projections
803
- * (zero extra persistence — derived fresh each compile). */
804
- loop_objective?: LoopObjective | null;
805
- rolling_summary?: RollingSummary | null;
806
- sub_goals?: SubGoal[];
807
- criterion_statuses?: CriterionStatus[];
808
- }
809
- export interface SessionState {
810
- task_id: string;
811
- call_count: number;
812
- success_trend: boolean[];
813
- }
814
- export declare function makeSessionState(taskId: string): SessionState;
815
- export interface AgentLoopResult {
816
- status: AgentStatus;
817
- response: LoopForgeResponse | null;
818
- }
819
- /** Why a loop stopped. Used by MCP session and vault persistence.
820
- * `completed` requires both success=true and should_continue=false.
821
- * `failed` is success=false + should_continue=false (agent gave up).
822
- * `cancelled` is manual stop via loopforge_stop. */
1095
+ /** Why a LOOP stopped — the LoopForge terminal reason (`loop_stop_reason` in
1096
+ * read surfaces). It is never the Agent's round outcome; `outcome` and
1097
+ * `blocker` are the Agent's report.
1098
+ *
1099
+ * `completed` requires outcome=success, should_continue=false and a closed
1100
+ * (or absent) active contract. It means the Agent's stop declaration passed
1101
+ * the gates; it does NOT imply `machineBackedSuccess` (the evidence posture's
1102
+ * separate machine fact). `failed` is outcome=failed with
1103
+ * should_continue=false. `cancelled` is manual stop via loopforge_stop.
1104
+ * `paused` exists in the type but a committed round never carries it; pause
1105
+ * is expressed by a session status, not a loop terminal reason. */
823
1106
  export type StopReason = "completed" | "failed" | "blocked" | "cancelled" | "max_rounds" | "stalled" | "enforcement_terminated"
824
1107
  /** Loop was paused by user or signal. */
825
1108
  | "paused"
@@ -853,21 +1136,31 @@ export interface EnforcementResult {
853
1136
  stopReason?: StopReason;
854
1137
  }
855
1138
  export declare function makeEnforcementResult(overrides?: Partial<EnforcementResult>): EnforcementResult;
856
- /** Context supplied to an embedding-owned provider before compilation. */
857
- export interface ExternalContextRequest {
858
- loopId: string;
859
- round: number;
860
- task: string;
861
- domain: string;
862
- /** The previously accepted evaluation, when one exists. */
863
- lastEvaluation?: SelfEvaluation;
864
- }
865
- export type ExternalContextProvider = (request: ExternalContextRequest) => Promise<string>;
866
1139
  export interface LoopTerminalEvent {
867
- success: boolean;
1140
+ /** v4.0.3: the loop lifecycle completed (the Agent's stop declaration
1141
+ * passed the gates). This is NOT a machine-verified task-success claim. */
1142
+ completed: boolean;
1143
+ /** v4.0.3: the last committed round's machine-backed success fact.
1144
+ * v4.0.4: null means there is NO committed posture to read (for example a
1145
+ * loop cancelled before any round commit). It is never synthesized as
1146
+ * false. */
1147
+ machineBackedSuccess: boolean | null;
1148
+ /** v4.0.3: the last committed round's evidence posture. */
1149
+ evidencePosture: EvidencePosture | null;
868
1150
  stopReason: StopReason;
1151
+ /** @deprecated v4.0.4: the historical name for `roundCursor`. It is NOT a
1152
+ * committed-round count. Kept for wire compatibility; new consumers should
1153
+ * read `roundCursor` / `committedRounds`. */
869
1154
  roundsCompleted: number;
870
- successTrajectory: boolean[];
1155
+ /** v4.0.4: the session's current round cursor (the round it is on or just
1156
+ * finished). It is not a count of committed rounds. */
1157
+ roundCursor: number;
1158
+ /** v4.0.4: committed evaluation rounds on the current branch, derived from
1159
+ * the same `loadCommittedHistory` window every read surface uses. Rollback
1160
+ * directives are events, not rounds, and are not counted. */
1161
+ committedRounds: number;
1162
+ /** v4.0.3: only machine-backed successful rounds, in order. */
1163
+ machineBackedSuccessTrajectory: boolean[];
871
1164
  loopId: string;
872
1165
  task: string;
873
1166
  lastEvaluation?: SelfEvaluation;
@@ -875,7 +1168,7 @@ export interface LoopTerminalEvent {
875
1168
  export type LoopTerminalSink = (event: LoopTerminalEvent) => Promise<void> | void;
876
1169
  /** A single flag raised during self-evaluation verification.
877
1170
  * Each flag identifies a specific inconsistency between the agent's
878
- * self-reported data and the loop's cross-round lineage. */
1171
+ * self-reported data and the committed round history. */
879
1172
  export interface VerificationFlag {
880
1173
  /** info | warn | error — determines how aggressively the compiler reacts. */
881
1174
  severity: "info" | "warn" | "error";
@@ -912,68 +1205,102 @@ export interface VerificationResult {
912
1205
  machineBackedSuccess: boolean;
913
1206
  }
914
1207
  export declare function makeVerificationResult(overrides?: Partial<VerificationResult>): VerificationResult;
915
- /** v3.8: The agent's self-report for a round — renamed from ExecutionReport
916
- * because these fields are claims, not evidence. The whole object is
917
- * optional; a mistyped optional field is dropped with a warning and never
918
- * rejects the round. */
1208
+ /** v3.8 / v4.0.6: The agent's self-report for a round. These fields are
1209
+ * claims, not evidence. The whole object is optional; a mistyped optional
1210
+ * field is dropped with a warning and never rejects the round. */
919
1211
  export interface ExecutionReport {
920
1212
  /** Files the agent says it changed. Informational — compared against the
921
1213
  * git observation, never trusted as the observation. */
922
1214
  files_changed?: string[];
923
- /** Test counts the agent reports. Informational. */
924
- tests_reported?: {
925
- passed: number;
926
- failed: number;
927
- skipped: number;
928
- } | null;
929
- /** Advisory claims about objective criteria. LENIENT: unknown/duplicate
930
- * criterion ids and malformed outcomes are dropped with a warning. */
931
- criterion_claims?: CriterionClaim[];
932
- /** Claims about ACTIVE contract items. STRICT: an unknown/duplicate item id
933
- * or an illegal outcome is a structural defect (contract_invalid). */
934
- contract_item_claims?: ContractItemClaim[];
1215
+ /** v4.0.6: THE claims channel. `cr-` ids are advisory objective-criterion
1216
+ * claims (lenient: unknown/malformed entries are dropped with a
1217
+ * diagnostic); `rci-` ids are strict ACTIVE contract-item claims (an
1218
+ * unknown/duplicate id or illegal outcome is `contract_invalid`). */
1219
+ claims?: ExecutionClaim[];
935
1220
  }
936
1221
  export declare function makeExecutionReport(overrides?: Partial<ExecutionReport>): ExecutionReport;
937
- /** v3.8: An advisory claim about an objective criterion. Lenient by design —
938
- * the criterion layer is advisory; the contract item layer is the machine
939
- * verification skeleton. */
940
- export interface CriterionClaim {
941
- /** cr-XXXXXXXX (or the criterion text for plain-text matching). */
942
- criterion_id: string;
943
- outcome: "met" | "remaining";
944
- }
945
- /** v3.8: A claim about an ACTIVE contract item, cited by the derived
946
- * rci-XXXXXXXX id the prompt rendered. */
947
- export interface ContractItemClaim {
948
- item_id: string;
1222
+ /** v4.0.6: ONE claim entry. The id prefix routes strictness: `cr-` is an
1223
+ * advisory criterion claim; `rci-` is a strict active-contract item claim.
1224
+ * A claim NEVER verifies anything — only machine observation can. */
1225
+ export interface ExecutionClaim {
1226
+ /** cr-XXXXXXXX criterion id or rci-XXXXXXXX active contract item id. */
1227
+ id: string;
949
1228
  outcome: "met" | "remaining";
950
1229
  }
951
- /** v3.8: One declared contract item. `verify_with` must name configured,
952
- * enabled, after-capable evidence commands — the declaration is strict.
953
- *
954
- * `subgoal_refs` lives HERE, not on the contract: a machine-verified item
955
- * backs exactly the sub-goals it names, so "item A verifies SubGoal 1, item B
956
- * verifies SubGoal 2" is expressible and `VerifiedSubGoalFact` attribution is
957
- * per-item instead of "every verified item backs every sub-goal". */
1230
+ /** v3.8/v3.9.5: One acceptance condition inside a Round Contract slice.
1231
+ * `description` states what must be true, not an activity. `verify_with`
1232
+ * must name configured, enabled, after-capable evidence commands — the
1233
+ * declaration is strict. A command may back several conditions, and one
1234
+ * condition may bind several commands. */
958
1235
  export interface ContractItemProposal {
1236
+ /** The acceptance condition: what must be true for this slice. */
959
1237
  description: string;
960
- /** cr-XXXXXXXX criterion ids this item is evidence for (or free text). */
961
- criterion_refs: string[];
962
- /** sg-XXXXXXXX sub-goals this item is evidence for. */
963
- subgoal_refs: string[];
964
- /** Evidence command ids (policy.evidence.commands[].name). */
1238
+ /** v3.9.4/v4.0.6: real cr-XXXXXXXX ids of ACTIVE criteria rendered in the
1239
+ * current prompt. Optional (defaults to `[]`). Free text and unknown ids
1240
+ * are `contract_invalid` when present. */
1241
+ criterion_refs?: string[];
1242
+ /** Evidence command ids (policy.evidence.commands[].name) that check this
1243
+ * acceptance condition. */
965
1244
  verify_with: string[];
966
1245
  }
967
- /** v3.8: A Round Contract proposal for the NEXT round. It becomes ACTIVE only
968
- * after the declaring round commits. Identity (rc-/rci-) is derived from
969
- * CONTENT ONLY — restating an unchanged contract keeps the same identity,
970
- * unlike a SubGoal whose id includes its declaration round. */
1246
+ /** v3.9.5: A Round Contract proposal for the NEXT round. It becomes ACTIVE
1247
+ * only after the declaring round commits. Identity (rc-/rci-) is derived
1248
+ * from CONTENT ONLY — restating an unchanged contract keeps the same
1249
+ * identity, unlike a SubGoal whose id includes its declaration round.
1250
+ *
1251
+ * `work_item` is the bounded deliverable this slice produces (an outcome,
1252
+ * not an activity). New declarations must provide it; it stays optional in
1253
+ * this persisted type because committed history may contain legacy
1254
+ * contracts without a label. `items[]` are the acceptance conditions;
1255
+ * `verify_with` remains item-level.
1256
+ *
1257
+ * The runtime validates structure, command bindings and references. It never
1258
+ * judges whether `work_item` sounds like a deliverable, whether an item
1259
+ * matches a command semantically, or whether a command is the right
1260
+ * acceptance test; that is Agent/operator semantic judgment. */
1261
+ /** A contract PROPOSAL carried by one evaluation. Three related objects must
1262
+ * not be conflated:
1263
+ * - the proposal: this object, for the NEXT round;
1264
+ * - the ACTIVE contract: the proposal once its declaring round commits,
1265
+ * governing the round that follows;
1266
+ * - `work_item`: the bounded deliverable for the slice governed by the
1267
+ * active contract. It becomes the prompt's `Current Task` only when
1268
+ * contract verification is available and the invocation has no explicit
1269
+ * `currentUserInstruction`; otherwise the contract remains a separate
1270
+ * committed fact and Current Task follows the invocation instruction or
1271
+ * working objective.
1272
+ * The proposal is never the contract of the round that declared it. */
971
1273
  export interface RoundContractProposal {
1274
+ /** The bounded deliverable this slice produces. Required for NEW
1275
+ * declarations, optional when reading legacy committed history. This is
1276
+ * the text the next prompt uses as `Current Task` when contract verification
1277
+ * is available and no explicit invocation instruction overrides it. */
972
1278
  work_item?: string;
973
- /** Files/directories the round may touch. Empty = no scope constraint. */
974
- scope: string[];
1279
+ /** v3.9.9/v4.0.6: the Agent's declared intended file boundary — an
1280
+ * optional, report-only intent statement. Omission and `[]` both mean "no
1281
+ * declared intent". It is rendered in prompts/receipts/audit and drives
1282
+ * drift reporting, but it does NOT participate in `rc-` identity and
1283
+ * grants no permission. Required for legacy reads of pre-3.9.9 proposals;
1284
+ * new declarations may omit it. */
1285
+ scope?: string[];
1286
+ /** v4.0.6: explicit replacement of the ACTIVE contract. This is the ONE
1287
+ * redirect modifier on the ONE contract channel; the target id binds it to
1288
+ * the exact contract the Agent saw, so a stale prompt cannot close a
1289
+ * different contract. The successor proposal is this same object's
1290
+ * `work_item` + `items`; its acceptance items must differ from the target's.
1291
+ * It does not participate in `rc-` identity. */
1292
+ supersedes?: ContractSupersede;
975
1293
  items: ContractItemProposal[];
976
1294
  }
1295
+ /** v4.0.6: the redirect modifier of a Round Contract proposal. It replaces the
1296
+ * former standalone `contract_transition` field. */
1297
+ export interface ContractSupersede {
1298
+ /** Must equal the ACTIVE contract id (`rc-XXXXXXXX`) rendered in this
1299
+ * round's prompt. */
1300
+ contract_id: string;
1301
+ /** Agent report, audit only, ≤ 500 chars. */
1302
+ reason?: string;
1303
+ }
977
1304
  /** v3.8: The machine's record of what a contract bound at its declaration
978
1305
  * round. Stamped by the runtime when the declaring round COMMITS (policy is
979
1306
  * not part of the Vault, so the command configuration in force at
@@ -987,10 +1314,104 @@ export interface ContractBinding {
987
1314
  /** v3.8: Runtime-derived contract item status. The agent may only claim
988
1315
  * `met` / `remaining`; the other three are machine-derived. */
989
1316
  export type ContractItemStatus = "pending" | "insufficient" | "contradicted" | "verified";
990
- /** v3.8: The round-level verification posture. `trusted` means every claim in
991
- * the round is machine-backed; `insufficient` means claims are unbacked but
992
- * not contradicted; `contradicted` means machine facts deny a claim. */
993
- export type RoundVerificationStatus = "trusted" | "insufficient" | "contradicted";
1317
+ /** v4.0.3: the ONE round-level evidence posture.
1318
+ *
1319
+ * It answers a deliberately narrow question: how well did this round's
1320
+ * machine observations cover its claims and its active contract? It is NOT a
1321
+ * task-success verdict and never decides `completed` — the Agent's stop
1322
+ * declaration still does that. `insufficient` and `unknown` are honest
1323
+ * coverage statements, not failures.
1324
+ *
1325
+ * The posture is DERIVED ONCE by the coordinator inside the committed
1326
+ * transaction and then persisted with it. Every read surface (prompt, state
1327
+ * file, replay, explain, audit, receipt, metrics, terminal) reads that one
1328
+ * copy; none re-derives it. The raw observations/evaluation/flags remain the
1329
+ * underlying facts — the posture is a compact projection of the same
1330
+ * transaction, not a second store.
1331
+ *
1332
+ * `unknown` never degrades to `verified` or to an empty result. */
1333
+ export type EvidencePostureStatus = "verified" | "insufficient" | "contradicted" | "unknown" | "not_applicable";
1334
+ /** v4.0.3: a compact, capped projection of one round's machine evidence.
1335
+ *
1336
+ * It deliberately carries no stdout/stderr, no file fingerprints and no full
1337
+ * command output: full observations stay in the committed transaction and are
1338
+ * read through `explain`/`replay`. Array caps are code constants (never
1339
+ * policy); `omitted` records how many entries the cap hid, while `status` is
1340
+ * computed from the COMPLETE data before any cap is applied. */
1341
+ export interface EvidencePosture {
1342
+ /** Logical round this posture describes. */
1343
+ round: number;
1344
+ /** Evaluation rounds carry observations; a rollback directive carries none. */
1345
+ kind: "evaluation" | "rollback";
1346
+ status: EvidencePostureStatus;
1347
+ /** ONLY `VerificationResult.machineBackedSuccess` may set this. No read
1348
+ * surface and no posture consumer re-derives it. */
1349
+ machineBackedSuccess: boolean;
1350
+ /** Policy fact at commit time: at least one enabled, after-capable
1351
+ * verification command existed. It explains `insufficient`/`unknown`; it
1352
+ * never decides completion. */
1353
+ verificationConfigured: boolean;
1354
+ /** The committed Git delta boundary. `observed` means the before/after pair
1355
+ * was comparable; `unknown` means Git participated but the boundary could
1356
+ * not be compared; `not_applicable` means Git did not participate. */
1357
+ workspace: {
1358
+ status: "observed" | "unknown" | "not_applicable";
1359
+ changedPathCount: number;
1360
+ };
1361
+ /** Agent-reported files vs the machine-observed Git change set. This is a
1362
+ * reconciliation, never a ledger of "verified files". */
1363
+ files: {
1364
+ reconciliation: "match" | "mismatch" | "unknown" | "not_applicable";
1365
+ reported: number;
1366
+ observed: number;
1367
+ } | null;
1368
+ /** Stable order: kind (git, custom), then providerId. `command` providers
1369
+ * are listed under `commands`, not here. */
1370
+ providers: Array<{
1371
+ providerId: string;
1372
+ kind: "git" | "custom";
1373
+ status: ObservationStatus;
1374
+ }>;
1375
+ /** Stable order: commandId. */
1376
+ commands: Array<{
1377
+ commandId: string;
1378
+ status: ObservationStatus;
1379
+ required: boolean;
1380
+ }>;
1381
+ /** Snapshot of the contract item statuses AT COMMIT TIME. Later policy or
1382
+ * command-configuration changes never rewrite it. */
1383
+ contract: {
1384
+ id: string;
1385
+ closure: "open" | "verified" | "blocked" | "superseded";
1386
+ items: Array<{
1387
+ id: string;
1388
+ status: ContractItemStatus;
1389
+ criterionRefs: string[];
1390
+ /** Deduped, capped historical explanation — never re-judged. */
1391
+ reasons: string[];
1392
+ }>;
1393
+ verifiedCount: number;
1394
+ insufficientCount: number;
1395
+ contradictedCount: number;
1396
+ pendingCount: number;
1397
+ } | null;
1398
+ /** Stable order: severity (error, warn, info), then check, ref, id. */
1399
+ findings: Array<{
1400
+ /** Stable `f-XXXXXXXX` finding id (`deriveFindingId`). */
1401
+ id: string;
1402
+ check: string;
1403
+ severity: "info" | "warn" | "error";
1404
+ ref?: string;
1405
+ }>;
1406
+ /** Entries hidden by the code caps. `status`/counts are computed from the
1407
+ * complete data, never from this capped projection. */
1408
+ omitted: {
1409
+ providers: number;
1410
+ commands: number;
1411
+ contractItems: number;
1412
+ findings: number;
1413
+ };
1414
+ }
994
1415
  /** v3.8: Machine observation status. A configured provider always produces an
995
1416
  * observation — the failure modes are recorded, not filtered away.
996
1417
  *
@@ -1001,6 +1422,26 @@ export type RoundVerificationStatus = "trusted" | "insufficient" | "contradicted
1001
1422
  * its own capture was aborted — a command killed mid-flight, say. A
1002
1423
  * collector deadline aborts the capture AS a timeout, so the round records
1003
1424
  * the runtime's measured cause, not the provider's. */
1425
+ /** v3.9.7: the four-state progress verdict shared by every consumer.
1426
+ * `not_applicable` = no progress-capable provider participated;
1427
+ * `unknown` = a progress-capable provider participated but its signal could
1428
+ * not be compared. Neither ever proves "no progress". */
1429
+ export type ProgressState = "changed" | "unchanged" | "unknown" | "not_applicable";
1430
+ /** v3.9.7: prompt-level freshness derived over one committed round. The
1431
+ * prompt level is a density decision; it never changes governance facts. */
1432
+ export type PromptFreshnessReason = "progress_changed" | "progress_unchanged" | "progress_unknown" | "no_progress_provider" | "after_command_activity" | "declared_evolution" | "no_observable_activity" | "no_previous_committed_round";
1433
+ export interface PromptFreshness {
1434
+ machineProgress: ProgressState;
1435
+ providers: string[];
1436
+ /** An after-phase command produced a structured, attributable result. */
1437
+ machineActivity: boolean;
1438
+ /** The committed evaluation declared evolution the compiler consumes. */
1439
+ declaredEvolution: boolean;
1440
+ /** false ONLY when no-activity is proven; unknown counts as fresh. */
1441
+ observableNewInformation: boolean;
1442
+ /** Stable, deterministic order. */
1443
+ reasons: PromptFreshnessReason[];
1444
+ }
1004
1445
  export type ObservationStatus = "observed" | "passed" | "failed" | "timeout" | "unavailable" | "error" | "aborted";
1005
1446
  /** v3.8: Common machine-observation fields. Observations are the factual
1006
1447
  * record of what the machine saw; they are persisted with the round and are
@@ -1076,8 +1517,25 @@ export interface CommandObservation extends MachineObservationBase {
1076
1517
  kind: "command";
1077
1518
  data: CommandObservationData;
1078
1519
  }
1520
+ /** v3.9.9: the normalized identity of the evidence range a progress fact
1521
+ * covers. `domain/object/scope` is a logical identity, not a file path:
1522
+ * matching is exact — no wildcards, no normalization, no subset inference —
1523
+ * and `version` must be equal because a different version means the
1524
+ * provider's fingerprint semantics changed. */
1525
+ export interface ProgressCoverage {
1526
+ /** Evidence domain, e.g. "workspace". */
1527
+ domain: string;
1528
+ /** Object/rule inside the domain, e.g. "git-motion". */
1529
+ object: string;
1530
+ /** Normalized coverage identity, e.g. "tracked_and_non_ignored_untracked". */
1531
+ scope: string;
1532
+ /** The provider's own evidence semantics version. */
1533
+ version: number;
1534
+ }
1079
1535
  export interface CustomObservation extends MachineObservationBase {
1080
1536
  kind: "custom";
1537
+ /** Provider-defined display data. It is a report, not a progress fact:
1538
+ * only Git workspace progress participates in stall/freshness rules. */
1081
1539
  data: Record<string, unknown>;
1082
1540
  }
1083
1541
  export type MachineObservation = GitObservation | CommandObservation | CustomObservation;
@@ -1146,34 +1604,31 @@ export interface EvidenceCapability {
1146
1604
  /** Human-readable capability gaps (the same text start/resume/status show). */
1147
1605
  warnings: string[];
1148
1606
  }
1149
- /** v3.8: A machine-verified sub-goal fact. DERIVED in cognitive-facts.ts,
1150
- * never persisted: it exists only while a committed contract item references
1151
- * the sub-goal AND that item is verified. It never writes SubGoal.status —
1152
- * `done` stays the agent's declaration. */
1153
- export interface VerifiedSubGoalFact {
1154
- subgoal_id: string;
1155
- contract_item_ids: string[];
1156
- verified_at_round: number;
1157
- }
1158
1607
  /** v3.8: The STABLE error codes every tool answers with. A client can branch
1159
1608
  * on these; the human sentence rides in `ToolError.message` and never doubles
1160
1609
  * as the code.
1161
1610
  *
1162
1611
  * - `evaluation_invalid` / `contract_invalid` / `policy_invalid` — a payload
1163
- * or configuration defect; the same roundId may be retried.
1164
- * - `round_id_required` / `round_id_mismatch` — the anchor is missing or no
1165
- * longer names the current round.
1612
+ * or configuration defect; the same submissionHandle may be retried.
1613
+ * - `projection_incomplete` — a code defect in the prompt projection: an
1614
+ * active normative ID was not rendered, so no prompt is delivered. Not
1615
+ * retryable by the agent.
1616
+ * - `submission_handle_required` — the handle is missing or structurally
1617
+ * malformed. The same call may be retried after obtaining the current
1618
+ * handle from `loopforge_status` (live session) or `loopforge_resume`
1619
+ * (lost prompt or no live session).
1620
+ * - `submission_handle_mismatch` — the handle no longer names the held
1621
+ * attempt. A `next`/`recover` submission returns the held prompt with a
1622
+ * warning and `ok: true` when one exists so the agent can recover the
1623
+ * response it missed; with no held prompt, or for `checkpoint`/
1624
+ * `gate_check`, it is this stable error.
1166
1625
  * - `session_not_found` / `state_unavailable` — the named session or read
1167
1626
  * model is not there.
1168
1627
  * - `invalid_argument` — the request itself is malformed at the tool boundary.
1169
- * - `gate_disabled` / `loop_already_running` — a state condition, not a defect.
1170
- *
1171
- * Note: a `loopforge_next` submission whose roundId no longer matches is NOT
1172
- * `round_id_mismatch` — it returns the held prompt with a warning and
1173
- * `ok: true` so the agent can recover the response it missed. That recovery
1174
- * contract (v3.0.1) is deliberate; `round_id_mismatch` is for the places with
1175
- * no held prompt to return (the gate preflight). */
1176
- export type ToolErrorCode = "evaluation_invalid" | "contract_invalid" | "policy_invalid" | "session_not_found" | "round_id_required" | "round_id_mismatch" | "state_unavailable" | "invalid_argument" | "gate_disabled" | "loop_already_running";
1628
+ * - `gate_disabled` / `gate_invalid` / `loop_already_running` /
1629
+ * `lease_conflict` — a state
1630
+ * condition, not a defect. */
1631
+ export type ToolErrorCode = "evaluation_invalid" | "contract_invalid" | "policy_invalid" | "projection_incomplete" | "session_not_found" | "submission_handle_required" | "submission_handle_mismatch" | "state_unavailable" | "invalid_argument" | "gate_disabled" | "gate_invalid" | "loop_already_running" | "lease_conflict" | "start_failed" | "loop_exists" | "legacy_history" | "operator_acceptance_conflict" | "recovery_invalid" | "recovery_disabled" | "recovery_unavailable" | "checkpoint_invalid" | "checkpoint_unavailable" | "checkpoint_failed" | "checkpoint_limit" | "restore_failed" | "restore_pending";
1177
1632
  /** v3.8: The structured error inside the uniform `{ok: false}` envelope. */
1178
1633
  export interface ToolError {
1179
1634
  code: ToolErrorCode;
@@ -1182,8 +1637,9 @@ export interface ToolError {
1182
1637
  /** Whether the fix is a corrected payload the agent may resend. */
1183
1638
  retryable: boolean;
1184
1639
  sessionId?: string;
1185
- roundId?: string;
1640
+ /** v4.0.0: the current held handle, when one exists, so the caller can
1641
+ * re-anchor without reconstructing it. */
1642
+ submissionHandle?: SubmissionHandle;
1186
1643
  details?: Record<string, unknown>;
1187
1644
  }
1188
- export declare function makeTaskId(taskDescription: string): string;
1189
1645
  //# sourceMappingURL=protocol.d.ts.map