@gajae-code/coding-agent 0.11.10 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/CHANGELOG.md +86 -2
  2. package/dist/types/cli/read-cli.d.ts +1 -0
  3. package/dist/types/cli.d.ts +8 -1
  4. package/dist/types/commands/deep-interview.d.ts +9 -0
  5. package/dist/types/commands/harness.d.ts +22 -0
  6. package/dist/types/commands/read.d.ts +6 -0
  7. package/dist/types/config/model-profile-activation.d.ts +1 -0
  8. package/dist/types/config/model-profile-contract.d.ts +2 -0
  9. package/dist/types/config/model-registry.d.ts +4 -0
  10. package/dist/types/config/provider-auth-health.d.ts +14 -0
  11. package/dist/types/config/provider-ranking.d.ts +59 -0
  12. package/dist/types/config/settings-schema.d.ts +86 -3
  13. package/dist/types/config/settings.d.ts +3 -0
  14. package/dist/types/extensibility/extensions/types.d.ts +43 -2
  15. package/dist/types/extensibility/shared-events.d.ts +6 -0
  16. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
  17. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
  18. package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
  19. package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
  20. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  21. package/dist/types/gjc-runtime/linux-proc.d.ts +22 -14
  22. package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
  23. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +112 -1
  24. package/dist/types/gjc-runtime/state-runtime.d.ts +3 -1
  25. package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
  26. package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
  27. package/dist/types/gjc-runtime/team-runtime.d.ts +2 -1
  28. package/dist/types/gjc-runtime/team-store.d.ts +12 -0
  29. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
  30. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +7 -0
  31. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
  32. package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
  33. package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
  34. package/dist/types/main.d.ts +1 -1
  35. package/dist/types/memories/index.d.ts +2 -0
  36. package/dist/types/modes/acp/acp-agent.d.ts +22 -9
  37. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  38. package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
  39. package/dist/types/modes/components/queue-pane.d.ts +8 -0
  40. package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
  41. package/dist/types/modes/components/read-tool-group.d.ts +4 -4
  42. package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
  43. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  44. package/dist/types/modes/components/tool-execution.d.ts +8 -0
  45. package/dist/types/modes/components/welcome.d.ts +1 -0
  46. package/dist/types/modes/controllers/event-controller.d.ts +3 -0
  47. package/dist/types/modes/interactive-mode.d.ts +7 -1
  48. package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
  49. package/dist/types/modes/types.d.ts +2 -0
  50. package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
  51. package/dist/types/runtime/memory-domain.d.ts +9 -0
  52. package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
  53. package/dist/types/runtime/memory-guard.d.ts +39 -0
  54. package/dist/types/runtime/memory-limit.d.ts +11 -0
  55. package/dist/types/runtime-mcp/manager.d.ts +8 -0
  56. package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
  57. package/dist/types/sdk/acp/final-text.d.ts +19 -0
  58. package/dist/types/sdk/acp/mcp.d.ts +23 -0
  59. package/dist/types/sdk/broker/lifecycle.d.ts +7 -0
  60. package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -1
  61. package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
  62. package/dist/types/sdk/bus/index.d.ts +18 -2
  63. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
  64. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
  65. package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
  66. package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
  67. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -4
  68. package/dist/types/sdk/bus/telegram-daemon.d.ts +23 -3
  69. package/dist/types/sdk/host/control/operations.d.ts +2 -1
  70. package/dist/types/sdk/host/host.d.ts +2 -0
  71. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  72. package/dist/types/sdk/lifecycle-session.d.ts +10 -1
  73. package/dist/types/sdk/startup-capability.d.ts +6 -0
  74. package/dist/types/session/agent-session.d.ts +51 -19
  75. package/dist/types/session/fallback-chain-controller.d.ts +18 -2
  76. package/dist/types/session/internal/managed-session-scope.d.ts +27 -0
  77. package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
  78. package/dist/types/session/session-manager.d.ts +59 -13
  79. package/dist/types/session/streaming-output.d.ts +60 -5
  80. package/dist/types/skill-state/active-state.d.ts +0 -4
  81. package/dist/types/skill-state/workflow-hud.d.ts +3 -0
  82. package/dist/types/task/executor.d.ts +6 -0
  83. package/dist/types/task/types.d.ts +36 -0
  84. package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
  85. package/dist/types/tools/browser/launch.d.ts +7 -0
  86. package/dist/types/tools/fetch.d.ts +17 -1
  87. package/dist/types/tools/output-meta.d.ts +21 -1
  88. package/dist/types/tools/read-internals.d.ts +12 -0
  89. package/dist/types/tools/read.d.ts +45 -1
  90. package/dist/types/tools/resource-gc.d.ts +23 -0
  91. package/dist/types/tools/tool-result.d.ts +7 -1
  92. package/package.json +9 -13
  93. package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
  94. package/scripts/capture-sticky-viewport-showcase.ts +292 -0
  95. package/scripts/generate-sdk-operation-inventory.ts +4 -0
  96. package/scripts/run-test-manifest.ts +6 -4
  97. package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
  98. package/scripts/verify-sticky-viewport-showcase.ts +611 -0
  99. package/src/capability/index.ts +8 -0
  100. package/src/cli/args.ts +14 -8
  101. package/src/cli/fast-help.ts +1 -1
  102. package/src/cli/read-cli.ts +2 -1
  103. package/src/cli.ts +49 -2
  104. package/src/commands/deep-interview.ts +29 -9
  105. package/src/commands/harness.ts +35 -12
  106. package/src/commands/read.ts +11 -2
  107. package/src/commands/sdk.ts +91 -7
  108. package/src/commands/team.ts +1 -1
  109. package/src/config/model-profile-activation.ts +1 -0
  110. package/src/config/model-profile-contract.ts +13 -0
  111. package/src/config/model-profiles.ts +24 -0
  112. package/src/config/model-registry.ts +21 -2
  113. package/src/config/provider-auth-health.ts +42 -0
  114. package/src/config/provider-ranking.ts +119 -0
  115. package/src/config/settings-schema.ts +84 -3
  116. package/src/config/settings.ts +254 -108
  117. package/src/defaults/gjc/skills/deep-interview/SKILL.md +229 -82
  118. package/src/defaults/gjc/skills/ralplan/SKILL.md +78 -26
  119. package/src/defaults/gjc/skills/team/SKILL.md +1 -1
  120. package/src/defaults/gjc/skills/ultragoal/SKILL.md +26 -16
  121. package/src/eval/py/executor.ts +7 -2
  122. package/src/extensibility/extensions/runner.ts +4 -0
  123. package/src/extensibility/extensions/types.ts +42 -4
  124. package/src/extensibility/shared-events.ts +5 -0
  125. package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -68
  126. package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
  127. package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
  128. package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
  129. package/src/gjc-runtime/deep-interview-state.ts +12 -921
  130. package/src/gjc-runtime/gc-render.ts +1 -0
  131. package/src/gjc-runtime/gc-runtime.ts +11 -1
  132. package/src/gjc-runtime/linux-proc.ts +70 -36
  133. package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
  134. package/src/gjc-runtime/ralplan-runtime.ts +979 -71
  135. package/src/gjc-runtime/state-runtime.ts +50 -12
  136. package/src/gjc-runtime/state-writer.ts +70 -222
  137. package/src/gjc-runtime/team-launch.ts +34 -5
  138. package/src/gjc-runtime/team-runtime.ts +970 -33
  139. package/src/gjc-runtime/team-store.ts +32 -0
  140. package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
  141. package/src/gjc-runtime/team-workers.ts +1 -0
  142. package/src/gjc-runtime/tmux-owner-isolation.ts +18 -0
  143. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
  144. package/src/gjc-runtime/ultragoal-runtime.ts +13 -7
  145. package/src/gjc-runtime/workflow-manifest.generated.json +97 -350
  146. package/src/gjc-runtime/workflow-manifest.ts +34 -179
  147. package/src/hooks/native-skill-hook.ts +17 -4
  148. package/src/hooks/skill-state.ts +1 -23
  149. package/src/internal-urls/docs-index.generated.ts +10 -11
  150. package/src/internal-urls/local-protocol.ts +23 -4
  151. package/src/internal-urls/local-root-gc.ts +127 -0
  152. package/src/main.ts +9 -5
  153. package/src/memories/index.ts +10 -0
  154. package/src/modes/DESIGN.md +47 -0
  155. package/src/modes/acp/acp-agent.ts +597 -67
  156. package/src/modes/acp/acp-event-mapper.ts +106 -12
  157. package/src/modes/acp/acp-mode.ts +39 -3
  158. package/src/modes/components/assistant-message.ts +123 -22
  159. package/src/modes/components/irc-sidebar.ts +176 -62
  160. package/src/modes/components/model-selector.ts +76 -5
  161. package/src/modes/components/notifications-settings-editor.ts +1 -1
  162. package/src/modes/components/oauth-selector.ts +42 -12
  163. package/src/modes/components/queue-pane.ts +55 -9
  164. package/src/modes/components/queued-message-selector.ts +53 -10
  165. package/src/modes/components/read-tool-group.ts +82 -14
  166. package/src/modes/components/session-observer-overlay.ts +187 -32
  167. package/src/modes/components/settings-selector.ts +60 -18
  168. package/src/modes/components/tool-execution.ts +138 -27
  169. package/src/modes/components/tool-status-header.ts +1 -4
  170. package/src/modes/components/welcome.ts +18 -3
  171. package/src/modes/controllers/command-controller.ts +4 -0
  172. package/src/modes/controllers/event-controller.ts +109 -27
  173. package/src/modes/controllers/extension-ui-controller.ts +23 -12
  174. package/src/modes/controllers/input-controller.ts +62 -6
  175. package/src/modes/controllers/selector-controller.ts +83 -37
  176. package/src/modes/interactive-mode.ts +127 -29
  177. package/src/modes/irc-observation-ledger.ts +71 -15
  178. package/src/modes/runtime-init.ts +20 -2
  179. package/src/modes/types.ts +2 -0
  180. package/src/modes/utils/ui-helpers.ts +94 -1
  181. package/src/prompts/agents/architect.md +9 -1
  182. package/src/prompts/agents/critic.md +9 -0
  183. package/src/prompts/agents/executor.md +1 -1
  184. package/src/prompts/system/system-prompt.md +0 -1
  185. package/src/prompts/tools/read.md +4 -2
  186. package/src/runtime/memory-domain.ts +66 -0
  187. package/src/runtime/memory-guard-contract.ts +73 -0
  188. package/src/runtime/memory-guard.ts +292 -0
  189. package/src/runtime/memory-limit.ts +50 -0
  190. package/src/runtime-mcp/manager.ts +26 -6
  191. package/src/runtime-mcp/smithery-auth.ts +17 -2
  192. package/src/runtime-mcp/smithery-connect.ts +11 -1
  193. package/src/sdk/acp/adapter.ts +8 -1
  194. package/src/sdk/acp/final-text.ts +40 -0
  195. package/src/sdk/acp/mcp.ts +26 -0
  196. package/src/sdk/broker/lifecycle.ts +107 -7
  197. package/src/sdk/bus/chat-daemon-cli.ts +2 -2
  198. package/src/sdk/bus/chat-daemon-control.ts +4 -3
  199. package/src/sdk/bus/config.ts +1 -1
  200. package/src/sdk/bus/control-drain-lease.ts +104 -0
  201. package/src/sdk/bus/index.ts +503 -60
  202. package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
  203. package/src/sdk/bus/prompt-reconciliation.ts +2 -1
  204. package/src/sdk/bus/rate-limit-pool.ts +8 -0
  205. package/src/sdk/bus/reconciliation-store.ts +224 -0
  206. package/src/sdk/bus/telegram-daemon-contract.ts +6 -4
  207. package/src/sdk/bus/telegram-daemon.ts +531 -53
  208. package/src/sdk/host/control/dispatch.ts +7 -1
  209. package/src/sdk/host/control/operations.ts +2 -1
  210. package/src/sdk/host/host.ts +25 -3
  211. package/src/sdk/host/query/handlers.ts +55 -0
  212. package/src/sdk/lifecycle-session.ts +19 -3
  213. package/src/sdk/mcp/server.ts +46 -18
  214. package/src/sdk/protocol/operation-inventory.generated.json +76 -0
  215. package/src/sdk/protocol/operation-registry.ts +8 -2
  216. package/src/sdk/session.ts +25 -2
  217. package/src/sdk/startup-capability.ts +6 -0
  218. package/src/session/agent-session.ts +720 -190
  219. package/src/session/fallback-chain-controller.ts +47 -8
  220. package/src/session/internal/managed-session-scope.ts +40 -10
  221. package/src/session/internal/native-publish-outcome.ts +8 -3
  222. package/src/session/memory-guard-checkpoint-participant.ts +131 -0
  223. package/src/session/session-manager.ts +1372 -42
  224. package/src/session/streaming-output.ts +262 -43
  225. package/src/setup/provider-onboarding.ts +19 -4
  226. package/src/skill-state/active-state.ts +0 -10
  227. package/src/skill-state/workflow-hud.ts +25 -2
  228. package/src/skill-state/workflow-mutation-guard.ts +65 -7
  229. package/src/task/executor.ts +11 -3
  230. package/src/task/index.ts +2 -0
  231. package/src/task/types.ts +22 -11
  232. package/src/task/ultragoal-redteam-activation.ts +75 -0
  233. package/src/tools/ask.ts +89 -69
  234. package/src/tools/browser/launch.ts +41 -6
  235. package/src/tools/fetch.ts +114 -23
  236. package/src/tools/output-meta.ts +176 -9
  237. package/src/tools/path-utils.ts +5 -1
  238. package/src/tools/read-internals.ts +44 -0
  239. package/src/tools/read.ts +1542 -310
  240. package/src/tools/resource-gc.ts +665 -125
  241. package/src/tools/tool-result.ts +14 -1
  242. package/src/web/search/providers/codex.ts +1 -1
  243. package/src/workflow/workflow-intent-diff.ts +4 -1
  244. package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
  245. package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
  246. package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
  247. package/src/gjc-runtime/deep-interview-draft.ts +0 -843
  248. package/src/gjc-runtime/deep-interview-payload.ts +0 -262
  249. package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
@@ -95,16 +95,15 @@ If this raw bundled skill is loaded by GJC's native skill loader through `/skill
95
95
 
96
96
  ## Corrupt current-session state recovery
97
97
 
98
- When deep-interview detects its own current-session state is corrupt, tampered, unreadable, or stale on resume, run `gjc state clear --force --mode deep-interview` before reseeding or restarting. Scope the clear to the current session via `--session-id`, the command payload, or `GJC_SESSION_ID`; it clears only deep-interview state for that session and never clears other skills or sessions.
99
- For ordinary diagnosis, run `gjc deep-interview sanity-check --session-id <id> --json` first, then use the issue's selector with `inspect` to read only the affected summary, topology, pending shell, round, facts, triggers, or floor. Repair a healthy, repairable local issue with its matching typed operation (`initialize-context`, `confirm-topology`, `record-answer`, or `apply-round-result`) and the current revision. Do not use grep/sed edits, direct `.gjc/` edits, generic envelope replacement, or `--force` as a repair mechanism; use generic `gjc state` only for the compatibility clear/handoff paths documented here.
98
+ When deep-interview detects its own current-session state is corrupt, tampered, unreadable, or stale on resume, run `gjc deep-interview clear --force` before reseeding or restarting. Scope the clear to the current session via `--session-id` or `GJC_SESSION_ID`; it clears only deep-interview state for that session and never clears other skills or sessions.
100
99
 
101
100
  ## Phase 0: Resolve Ambiguity Threshold (blocking prerequisite)
102
101
 
103
102
  Complete this phase before Phase 1, before brownfield exploration, before GJC state persistence, before Round 0, and before any ambiguity scoring. Do not continue if the resolved threshold and source are unknown.
104
103
 
105
- 1. **Inspect the native summary first**:
106
- - Run `gjc deep-interview inspect --session-id <id> --selector summary --json`.
107
- - If the summary contains a finite `threshold` and its preserved source is available from native state, use those values, set `<resolvedThreshold>`, `<resolvedThresholdPercent>`, and `<resolvedThresholdSource>`, and skip optional settings-file reads. This is the normal `/skill:deep-interview` path because the native hook already resolved settings quietly before loading the skill.
104
+ 1. **Prefer pre-resolved native state**:
105
+ - First inspect active deep-interview state with `gjc deep-interview read --json`.
106
+ - If state contains a finite numeric `threshold` and a non-empty `threshold_source`, use those values, set `<resolvedThreshold>`, `<resolvedThresholdPercent>`, and `<resolvedThresholdSource>`, and skip optional settings-file reads. This is the normal `/skill:deep-interview` path because the native hook already resolved settings quietly before loading the skill.
108
107
  2. **Only if native state lacks a resolved threshold, read threshold settings in runtime precedence order**:
109
108
  - YAML config first: read the **single** modern config path the environment selects — `$GJC_CODING_AGENT_DIR/config.yml` when `GJC_CODING_AGENT_DIR` is set, else `$GJC_CONFIG_DIR/agent/config.yml` when `GJC_CONFIG_DIR` is set, else `~/.gjc/agent/config.yml`. Do not cascade through the other YAML locations when the selected one is absent or invalid.
110
109
  - Then JSON settings: project settings `./.gjc/settings.json`, then user settings `[$GJC_CONFIG_DIR|~/.gjc]/settings.json`.
@@ -120,20 +119,20 @@ Deep Interview threshold: <resolvedThresholdPercent> (source: <resolvedThreshold
120
119
  ```
121
120
 
122
121
  5. **Carry threshold source forward mechanically**:
123
- - Pass threshold/source only as bounded setup evidence to `initialize-context`; native state owns the envelope, revision, receipt, lifecycle, derived ambiguity, and later updates. Do not reconstruct or submit a generic state envelope during normal flow.
122
+ - Substitute `<resolvedThreshold>`, `<resolvedThresholdPercent>`, and `<resolvedThresholdSource>` throughout the remaining instructions before continuing.
123
+ - Include `threshold_source` in the first `gjc deep-interview write` payload and preserve it on later state updates; do not edit `.gjc/_session-{sessionid}/state` files directly unless an explicit force override is active.
124
124
  - Include both threshold and source in the final spec metadata.
125
125
  - Read any `language` object from active deep-interview state and carry `language.instruction` forward mechanically. If absent, default to English unless `{{ARGUMENTS}}` makes another user/session language obvious or the user explicitly requests another language. Do not add language-specific special cases.
126
126
 
127
127
  ## Phase 0.5: Suitability Gate
128
128
 
129
- Run this gate after the Phase 0 threshold marker and before Phase 1, brownfield exploration, typed initialization, Round 0, ambiguity scoring, or spec writing.
129
+ Run this gate after the Phase 0 threshold marker and before Phase 1, brownfield exploration, `gjc deep-interview write`, Round 0, ambiguity scoring, or spec writing.
130
130
 
131
131
  If the user request appended after this skill as the final `User:` line is already clear, bounded, low-risk, and asks for a quick fix, single change, known file/symbol edit, explicit command, or direct answer:
132
132
 
133
133
  1. **Stop deep-interview immediately**:
134
- - First inspect current-session state with `gjc deep-interview inspect --session-id <current-session-id> --selector summary --json`.
135
- - For compatibility-only recovery where typed inspection is unavailable, `gjc state read --mode deep-interview --json` may confirm whether this narrow clear is safe; never use it to rebuild or replace state.
136
- - Clear through `gjc state clear --force --mode deep-interview --json` only when the state is a newly seeded empty interview: no recorded `rounds`, no `spec_path`, no `handoff_from`, no final/pending spec, and no user-confirmed topology.
134
+ - First inspect current-session state with `gjc deep-interview read --json` (include `--session-id <current-session-id>` when available).
135
+ - Clear through `gjc deep-interview clear --force --json` only when the state is a newly seeded empty interview: no recorded `rounds`, no `spec_path`, no `handoff_from`, no final/pending spec, and no user-confirmed topology.
137
136
  - If state already contains rounds, a spec path, handoff metadata, pending approval, or confirmed topology, do not clear it. Preserve the active interview and ask the user whether to continue, cancel, or explicitly clear the workflow.
138
137
  - Do not initialize deep-interview state.
139
138
  - Do not run Round 0.
@@ -182,17 +181,46 @@ Run this phase only when the active deep-interview state or invocation indicates
182
181
  - Preferred: pass the spec markdown **inline** to the native deep-interview write command (`--write … --spec "<markdown>"`) — no scratch file is needed. The CLI is the only sanctioned writer for `.gjc/_session-{sessionid}/specs`.
183
182
  - Only if a spec is too large to pass inline, stage it with the `write` tool to a system temp directory (`os.tmpdir()`/`$TMPDIR`, `/tmp`, `/var/tmp`) outside the project tree, then pass that path to `--spec`. The planning phase-boundary block tolerates these neutral temp writes; never stage interview artifacts inside the repo or under `.gjc/`, and do not improvise repo-relative scratch files.
184
183
 
185
- 4. **Initialize through a CLI-owned draft.** Create an `initialize-context` draft, edit only its bounded fields, check it, then consume it through the typed command. Never serialize a setup request, envelope, or derived values inline:
186
- ```sh
187
- gjc deep-interview draft create --for initialize-context --session-id <id> --json
188
- # Capture draft_id and draft_revision from the response.
189
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <draft_revision> --op set --path /type --value greenfield --json
190
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op set --path /initial_idea --value "<prompt-safe idea>" --json
191
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op set --path /threshold_source --value "<source>" --json
192
- gjc deep-interview draft check --draft-id <draft_id> --json
193
- gjc deep-interview initialize-context --draft-id <draft_id> --expected-draft-revision <latest_draft_revision> --json
184
+ 4. **Initialize state** via `gjc deep-interview write --input '<json>'`:
185
+
186
+ ```json
187
+ {
188
+ "active": true,
189
+ "current_phase": "interviewing",
190
+ "state": {
191
+ "interview_id": "<uuid>",
192
+ "type": "greenfield|brownfield",
193
+ "initial_idea": "<prompt-safe initial-context summary or user input>",
194
+ "initial_context_summary": "<summary if oversized, else null>",
195
+ "rounds": [],
196
+ "established_facts": [],
197
+ "current_ambiguity": 1.0,
198
+ "threshold": <resolvedThreshold>,
199
+ "threshold_source": "<resolvedThresholdSource>",
200
+ "language": "<existing language object from active state, if present>",
201
+ "trace_summary": "<bounded trace summary when --trace is active, else null>",
202
+ "codebase_context": null,
203
+ "topology": {
204
+ "status": "pending|confirmed|legacy_missing",
205
+ "confirmed_at": null,
206
+ "components": [],
207
+ "deferrals": [],
208
+ "last_targeted_component_id": null
209
+ },
210
+ "ontology_snapshots": [],
211
+ "auto_researched_rounds": [],
212
+ "auto_answered_rounds": [],
213
+ "lateral_reviews": [],
214
+ "lateral_panel_failures": 0,
215
+ "auto_answer_streak": 0,
216
+ "refined_rounds": [],
217
+ "closure_overrides": [],
218
+ "restated_goal": null,
219
+ "ambiguity_milestone": "initial",
220
+ "architect_failures": 0
221
+ }
222
+ }
194
223
  ```
195
- `draft create` records the state base revision; every edit returns the next `draft_revision`. The native runtime validates, consumes, stamps, and owns the complete state. Retain the returned state revision for inspection only; mutations consume their own checked draft.
196
224
 
197
225
  5. **Announce the interview** to the user:
198
226
 
@@ -239,20 +267,46 @@ Options should include contextually relevant choices such as **Looks right**, **
239
267
 
240
268
  The Round 0 `ask` call MUST include `deepInterview.round = 0`, `deepInterview.component = "review-topology"`, `deepInterview.dimension = "topology"`, `deepInterview.intent_contract.items` containing the exact displayed locked-intent items, and `deepInterview.intent_contract.confirmation_options` listing only the displayed affirmative labels that lock the proposal (normally **Looks right**). The runtime recorder canonicalizes and locks this contract only when the user selects one of those labels; correction, deferral, free-text, and clarification answers never lock the pre-question proposal. Do not manually copy raw free text into intent evidence, and do not continue if this required recorder write fails.
241
269
 
242
- 3. **Lock topology through a CLI-owned draft** after the answer. Create a `confirm-topology` draft, use a valueless append on a missing object-item array to add an `{}` scaffold, set scalar leaves, and check it. A valueless append on a missing scalar-item array initializes `[]`; on an existing scalar-item array, append still requires `--value` or `--value-file`. For a topology with zero deferrals, initialize `/deferred_components` with that valueless scalar-array append, then consume it:
243
- ```sh
244
- gjc deep-interview draft create --for confirm-topology --session-id <id> --json
245
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <draft_revision> --op append --path /components --json
246
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op set --path /components/0/id --value <component_id> --json
247
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op set --path /components/0/name --value "<component name>" --json
248
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op append --path /deferred_components --json
249
- gjc deep-interview draft check --draft-id <draft_id> --json
250
- gjc deep-interview confirm-topology --draft-id <draft_id> --expected-draft-revision <latest_draft_revision> --json
270
+ 3. **Lock topology into state** after the answer. Store a normalized component list and confirmation timestamp:
271
+
272
+ ```json
273
+ {
274
+ "topology": {
275
+ "status": "confirmed",
276
+ "confirmed_at": "<ISO-8601 timestamp>",
277
+ "components": [
278
+ {
279
+ "id": "component-slug",
280
+ "name": "Component Name",
281
+ "description": "Confirmed top-level outcome",
282
+ "status": "active|deferred",
283
+ "evidence": ["initial prompt phrase or brownfield citation"],
284
+ "clarity_scores": {
285
+ "goal": null,
286
+ "constraints": null,
287
+ "criteria": null,
288
+ "context": null
289
+ },
290
+ "weakest_dimension": null
291
+ }
292
+ ],
293
+ "deferrals": [
294
+ {
295
+ "component_id": "component-slug",
296
+ "reason": "User-confirmed deferral reason",
297
+ "confirmed_at": "<ISO-8601 timestamp>"
298
+ }
299
+ ],
300
+ "last_targeted_component_id": null
301
+ }
302
+ }
251
303
  ```
252
- The recorder still persists `state.intent_contract` from the Round 0 `ask` answer. The runtime validates pending/legacy state, preserves declared ordering, detects conflicting confirmations, derives component state, and returns the new revision. Do not replace `topology` through `gjc state write`.
253
- It contains the four exact categories `artifact`, `surface`, `integration`, and `constraint`; every item has a unique category-prefixed ID (for example `surface:review`). The recorder canonically sorts items, persists the full SHA-256 manifest digest, and binds confirmation to a redacted answer-hash reference. Before spec persistence, include every preserved locked ID literally in the final spec. For a proposed missing locked ID, ask one intent-review question through `ask`; the runtime records `pending` unless the user selects an exact approval option, and spec persistence/handoff fail closed for missing, stale, or unrecorded reduction-review evidence. Intent review authorizes only that output reduction, never execution or handoff.
254
304
 
255
- 4. **Legacy state migration:** When a resumed legacy interview lacks confirmed topology and no final `spec_path` exists, run Round 0 and use `confirm-topology` before the next ambiguity scoring pass. If a final spec already exists, do not rewrite history; note in any handoff that topology was not captured for that legacy interview.
305
+ In the same Round 0 answer, the runtime recorder persists `state.intent_contract` version 1 from `deepInterview.intent_contract.items`. It contains the four exact categories `artifact`, `surface`, `integration`, and `constraint`; every item has a unique category-prefixed ID (for example `surface:review`) and a bounded non-empty statement. The recorder canonically sorts items, persists the full SHA-256 manifest digest, and binds confirmation to a redacted answer-hash reference. The confirmation answer locks this manifest before Round 1; later prose, inferred implementation detail, raw answer content, or a regenerated digest cannot replace it.
306
+
307
+ Before spec persistence, include every preserved locked ID literally in the final spec. Additions and clarifications need no extra question; the runtime derives and persists a `not_required` review when every locked ID remains. For any proposed missing locked ID, ask one intent-review question through `ask` and include `deepInterview.intent_review` with the proposed `observed_items`, every `supporting_substitution`, and the exact `approval_options` labels that count as approval. The runtime recorder writes `pending` when the user does not approve and writes `approved` only when an approval option is selected, binding the review to the recorder-generated answer hash without storing raw answer text. Approved reductions require every removed ID to map to an observed replacement ID. Spec persistence and handoff fail closed for missing, pending, malformed, stale, or unrecorded reduction review evidence. Intent review approves only that output reduction and never authorizes execution or ralplan handoff.
308
+
309
+ 4. **Legacy state migration:** When resuming an existing `deep-interview` state file that lacks `topology`, treat it as `"status": "legacy_missing"`. If no final `spec_path` exists yet, run Round 0 before the next ambiguity scoring pass and then continue with the existing transcript. If a final spec already exists, do not rewrite history; note in any handoff that topology was not captured for that legacy interview.
256
310
 
257
311
  5. **Single-component pass-through:** If the user confirms one active component, Phase 2 proceeds with the existing flow while still carrying `topology.components[0]` into scoring and spec output.
258
312
 
@@ -316,19 +370,9 @@ Options should include contextually relevant choices plus free-text, translated/
316
370
 
317
371
  After applying `language.instruction` to the visible question, options, and generated rationale, apply the self-proofread once to new prose only (DIPP-5); preserve only the Round/Component/Targeting/Ambiguity line structure, fixed labels, numeric ambiguity value, component/target identifiers, and `deepInterview.*` metadata keys. Do not exempt generated natural-language rationale such as Why now.
318
372
 
319
- When calling `ask`, SHOULD include optional structured metadata so the runtime can record the round without manual state writes: `deepInterview.round_id?`, `deepInterview.round`, `deepInterview.component`, `deepInterview.dimension`, and `deepInterview.ambiguity`. Keep this metadata aligned with the visible Round/Component/Targeting/Ambiguity line. Recorder-first remains mandatory. If the runtime did not record the answer shell, inspect `pending` or `round` to obtain its identity, then create a `record-answer` draft with that identity, edit scalar leaves, scaffold option arrays, and consume it:
320
- ```sh
321
- gjc deep-interview draft create --for record-answer --session-id <id> --round <n> --question-id <id> [--round-id <id>] [--component-id <id>] [--dimension <dimension>] --json
322
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <draft_revision> --op set --path /question --value "<question>" --json
323
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op append --path /answer/selected_options --json
324
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op set --path /answer/selected_options/0 --value "<selected option>" --json
325
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op set --path /answer/custom_input --null --json
326
- gjc deep-interview draft check --draft-id <draft_id> --json
327
- gjc deep-interview record-answer --draft-id <draft_id> --expected-draft-revision <latest_draft_revision> --json
328
- ```
329
- Do not recreate transcript, rounds, or generic state JSON.
373
+ When calling `ask`, SHOULD include optional structured metadata so the runtime can record the round without manual state writes: `deepInterview.round_id?`, `deepInterview.round`, `deepInterview.component`, `deepInterview.dimension`, and `deepInterview.ambiguity`. Keep this metadata aligned with the visible Round/Component/Targeting/Ambiguity line; if metadata cannot be supplied, the legacy formatted question text remains the fallback.
330
374
 
331
- If the `ask` tool returns `clarificationQuestion`, treat it as a non-answer about the displayed choices. Answer the clarification briefly from the current interview context, then call `ask` again with the exact original question, options, and `deepInterview.*` metadata. A clarification bypasses Step 2b′ auto-answer, Step 2b″ free-text refine, Step 2c ambiguity scoring, Step 2d apply-and-report, and Step 2e soft-limit checks; it must not be recorded as a round answer. This does not violate the one-question-per-round rule because the round remains unresolved until the user submits a real listed option or `Other` answer.
375
+ If the `ask` tool returns `clarificationQuestion`, treat it as a non-answer about the displayed choices. Answer the clarification briefly from the current interview context, then call `ask` again with the exact original question, options, and `deepInterview.*` metadata. A clarification bypasses Step 2b′ auto-answer, Step 2b″ free-text refine, Step 2c ambiguity scoring, Step 2d progress reporting, and Step 2e state updates; it must not be recorded as a round answer. This does not violate the one-question-per-round rule because the round remains unresolved until the user submits a real listed option or `Other` answer.
332
376
 
333
377
  ### Step 2b′: Auto-Answer Opted-Out Questions
334
378
 
@@ -362,17 +406,24 @@ Ambiguity-raising triggers:
362
406
 
363
407
  Use **mechanism A** for every ambiguity rise: a trigger LOWERS the affected component/dimension clarity score, and the existing weighted formula raises ambiguity. There is **no separate penalty term**; ambiguity remains bounded by the same greenfield/brownfield formula.
364
408
 
365
- **Native ambiguity and floor.** Submit candidate component scores, trigger/fact operations, ontology evidence, targeting, and bookkeeping in `RoundResult`; the runtime alone derives weighted ambiguity, floor, effective ambiguity, milestone, ontology stability, trigger correspondence, rotation, and auto-resolution streak. Do not calculate, assert, or persist any of those derived values in the request.
409
+ **Deterministic ambiguity floor (runtime-enforced).** The runtime independently computes a code-level floor from persisted state and clamps every reported ambiguity to `max(reported, floor)` at write time — the scorer cannot under-report below what code can objectively measure:
410
+
411
+ - `+0.10` per established fact marked `disputed` that has no `superseded_by` resolution (contradiction pressure)
412
+ - `+0.05` per active topology component whose goal/constraints/criteria clarity is still unscored (gap pressure — persist `topology.components[].clarity_scores` every round or the floor blocks convergence)
413
+ - `+0.05 × (auto-answered rounds / scored rounds)` (assumption dilution)
366
414
 
367
- The native floor retains contradiction pressure, unscored active-component pressure, and auto-answer dilution. A disputed fact blocks convergence until it is resolved through the typed fact operation; never delete contradicted history. When the response reports a clamp, show the returned floor and dominant cause rather than inventing a score.
415
+ Cooperate with the floor rather than fight it:
416
+ - Replacing an already-scored answer for the same round (a retraction/pivot) automatically marks that round's established facts as disputed; ambiguity rises mechanically even when no trigger is reported. Treat a floor-driven rise as trigger evidence and score the affected dimensions accordingly.
417
+ - A disputed fact keeps the floor at or above `0.10` — above the default threshold — so convergence is blocked until the dispute is resolved: either the user re-confirms the original fact (set `disputed: false`) or the superseding decision is recorded as a new established fact and the old fact gets `superseded_by: <new fact id>`. Never delete the contradicted fact.
418
+ - When the effective score was clamped upward, the persisted round carries `reported_ambiguity` (your raw score) and `ambiguity_floor`; report the floor and its dominant cause in the Step 2d table instead of pretending the raw score held.
368
419
 
369
420
  The rise is SILENT: no modal, no forced-resolution step, and no dedicated conflict UI. Surface it through the normal per-round report and by targeting the next question at the affected component/dimension.
370
421
 
371
- Structured scorer output is required. Include `triggers`, `trigger_status`, `affected_component`, `affected_dimension`, `prior_dimension_score`, `new_dimension_score`, `evidence`, `contradicted_established_fact` when relevant, and `disputed_unresolved_rationale` when applicable. Do not include prior/new ambiguity, floor, effective ambiguity, or milestone assertions.
422
+ Structured scorer output is required. Include `triggers`, `trigger_status`, `affected_component`, `affected_dimension`, `prior_dimension_score`, `new_dimension_score`, `prior_ambiguity`, `new_ambiguity`, `evidence`, `contradicted_established_fact` when relevant, and `disputed_unresolved_rationale` when applicable.
372
423
 
373
424
  Established-facts maintenance: promote stable confirmed decisions into `state.established_facts` with source/evidence; when a new answer contradicts an established fact, mark the fact disputed and preserve the contradicted fact instead of deleting it. When the user later confirms the new direction, record the superseding decision as a new established fact and set `superseded_by: <new fact id>` on the disputed fact — that is the only way to release the deterministic floor pressure while keeping the audit trail.
374
425
 
375
- TRANSITION VALIDATION: if a trigger is present, the affected dimension must not improve unless the trigger is explicitly marked disputed or unresolved with rationale. The runtime validates and returns the authoritative ambiguity transition.
426
+ TRANSITION VALIDATION: if a trigger is present, the affected dimension must not improve and overall ambiguity must rise vs the prior scored round, unless the trigger is explicitly marked disputed or unresolved with rationale.
376
427
 
377
428
  Convergence Pacing deferral: do not add a min-round floor, score-drop cap, confidence dampening, or other explicit pacing brake. Bidirectional scoring is the pacing mechanism.
378
429
 
@@ -413,7 +464,7 @@ Also identify:
413
464
  - weakest_dimension: the single lowest-confidence dimension for that component this round
414
465
  - weakest_dimension_rationale: one sentence explaining why this component/dimension pair is the highest-leverage target for the next question
415
466
  - component_scores: object keyed by component id, with per-dimension scores and gaps
416
- - structured_scorer_output: object containing triggers, trigger_status, affected_component, affected_dimension, prior_dimension_score, new_dimension_score, evidence, contradicted_established_fact when relevant, and disputed_unresolved_rationale when applicable; do not include ambiguity, floor, or milestone values
467
+ - structured_scorer_output: object containing triggers, trigger_status, affected_component, affected_dimension, prior_dimension_score, new_dimension_score, prior_ambiguity, new_ambiguity, evidence, contradicted_established_fact when relevant, and disputed_unresolved_rationale when applicable
417
468
 
418
469
  5. Ontology Extraction: Identify all key entities (nouns) discussed in the transcript.
419
470
 
@@ -428,51 +479,147 @@ For each entity provide:
428
479
  Respond as JSON. Include an additional "ontology" key containing the entities array alongside the dimension scores.
429
480
  ```
430
481
 
431
- **Ontology input:** provide entities, relationships, and concise reasoning in `RoundResult`. The runtime determines first-round/no-entity handling, exact-name stability, deterministic renamed matching, counts, ratio, and snapshot persistence. Report the returned ontology result; do not send caller-computed counts, ratios, or snapshots.
482
+ **Calculate ambiguity:**
432
483
 
433
- ### Step 2d: Apply Round Result and Report Progress
434
- After `ask` has recorded (or `record-answer` has recovered) the answer shell, inspect `pending` or `round` for its identity. Create an `apply-round-result` draft, edit only bounded scorer evidence, check it, and consume it once:
435
- ```sh
436
- gjc deep-interview draft create --for apply-round-result --session-id <id> --round-key <round_key> --json
437
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <draft_revision> --op set --path /global_scores/goal --value 0.8 --json
438
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op append --path /component_updates --json
439
- gjc deep-interview draft edit --draft-id <draft_id> --expected-draft-revision <next_draft_revision> --op set --path /component_updates/0/component_id --value <component_id> --json
440
- gjc deep-interview draft check --draft-id <draft_id> --json
441
- gjc deep-interview apply-round-result --draft-id <draft_id> --expected-draft-revision <latest_draft_revision> --json
442
- ```
443
- `RoundResult` remains candidate scores, component updates, triggers, fact operations, ontology input, targeting, and bookkeeping only. The runtime performs one authoritative transaction, returns native-derived scoring and the new revision, and rejects stale, conflicting, malformed, or unrecoverable state. Never enrich a round through `gjc state write`.
484
+ Greenfield: `ambiguity = 1 - (goal × 0.40 + constraints × 0.30 + criteria × 0.30)`
485
+ Brownfield: `ambiguity = 1 - (goal × 0.35 + constraints × 0.25 + criteria × 0.25 + context × 0.15)`
486
+ Brownfield adds the 15% Context Clarity dimension (Goal/Constraint/Criteria become 35/25/25) because safely modifying existing code requires understanding the system being changed.
444
487
 
445
- After the typed transaction succeeds, consume `<native>.native_projection` as the version 1 native projection. Render only the paths listed below; do not report candidate values, inspect-state values, locally calculated values, names, weights, gaps, thresholds, ratios, causes, or milestone transitions that the projection does not expose.
488
+ **Calculate ontology stability:**
446
489
 
447
- ```text
490
+ **Round 1 special case:** For the first round, skip stability comparison. All entities are "new". Set stability_ratio = N/A. If any round produces zero entities, set stability_ratio = N/A (avoids division by zero).
491
+
492
+ For rounds 2+, compare with the previous round's entity list:
493
+ - `stable_entities`: entities present in both rounds with the same name
494
+ - `changed_entities`: entities with different names but the same type AND >50% field overlap (treated as renamed, not new+removed)
495
+ - `new_entities`: entities in this round not matched by name or fuzzy-match to any previous entity
496
+ - `removed_entities`: entities in the previous round not matched to any current entity
497
+ - `stability_ratio`: (stable + changed) / total_entities (0.0 to 1.0, where 1.0 = fully converged)
498
+
499
+ This formula counts renamed entities (changed) toward stability. Renamed entities indicate the concept persists even if the name shifted — this is convergence, not instability. Two entities with different names but the same `type` and >50% field overlap should be classified as "changed" (renamed), not as one removed and one added.
500
+
501
+ **Show your work:** Before reporting stability numbers, briefly list which entities were matched (by name or fuzzy) and which are new/removed. This lets the user sanity-check the matching.
502
+
503
+ Store the ontology snapshot (entities + stability_ratio + matching_reasoning) in `state.ontology_snapshots[]`.
504
+
505
+ ### Step 2d: Report Progress
506
+
507
+ After scoring, show the user their progress:
508
+
509
+ ```
448
510
  Round {n} complete.
449
511
 
450
- Ambiguity: prior {<native>.native_projection.prior_effective_ambiguity}; current {<native>.native_projection.effective_ambiguity} ({<native>.native_projection.direction})
451
- Floor: {<native>.native_projection.floor}
452
- Milestone: {<native>.native_projection.ambiguity_milestone}
453
- Topology: target {<native>.native_projection.targeting.target_component_id}; active {<native>.native_projection.topology_counts.active}; deferred {<native>.native_projection.topology_counts.deferred}; total {<native>.native_projection.topology_counts.total}
454
- Ontology: stable {<native>.native_projection.ontology_counts.stable}; changed {<native>.native_projection.ontology_counts.changed}; new {<native>.native_projection.ontology_counts.new}
455
- Next target: {<native>.native_projection.targeting.target_component_id} / {<native>.native_projection.targeting.target_dimension}
456
- Auto-answer streak: {<native>.native_projection.transition.auto_answer_streak}
512
+ | Dimension | Score | Weight | Weighted | Gap |
513
+ |-----------|-------|--------|----------|-----|
514
+ | Goal | {s} | {w} | {s*w} | {gap or "Clear"} |
515
+ | Constraints | {s} | {w} | {s*w} | {gap or "Clear"} |
516
+ | Success Criteria | {s} | {w} | {s*w} | {gap or "Clear"} |
517
+ | Context (brownfield) | {s} | {w} | {s*w} | {gap or "Clear"} |
518
+ | **Ambiguity** | | | **{prior_score}% -> {score}% {up|down|flat}** | {if up: trigger name such as "A direct contradiction"} |
519
+ | **Floor** (only when clamped) | | | **{floor}%** | {dominant cause: disputed fact / unscored component / auto-answer dilution} |
520
+
521
+ **Topology:** Targeted {target_component_name} | Active: {active_component_count} | Deferred: {deferred_component_count} | Next rotation after: {last_targeted_component_id}
522
+
523
+ **Ontology:** {entity_count} entities | Stability: {stability_ratio} | New: {new} | Changed: {changed} | Stable: {stable}
524
+ **Milestone:** {prior_milestone} → {current_milestone}{milestone_transition ? " — lateral panel convened" : ""}
525
+
526
+ **Next target:** {target_component_name} / {weakest_dimension} — {weakest_dimension_rationale}
527
+
528
+ {score <= threshold ? "Clarity threshold met! Ready to proceed." : "Focusing next question on: {weakest_dimension}"}
529
+
530
+ ```
531
+
532
+ Apply `language.instruction` when present before showing this progress report so status text, gaps, and next-target phrasing stay in the preserved session language.
533
+
534
+ Then apply the self-proofread once (DIPP-5) to narrative status text, generated prose cells, gaps, and next-target phrasing; preserve only table structure, fixed status labels, scores, weights, component ids, and trigger tokens.
535
+
536
+ ### Step 2e: Update State
537
+
538
+ Update state in two phases. The `ask` answer is first recorded by the runtime as an `answered` shell. Scoring then enriches the same round record to `scored` with global scores, per-component `topology.components[].clarity_scores`, `topology.components[].weakest_dimension`, trigger metadata, established-facts changes, ontology snapshot, `topology.last_targeted_component_id`, `auto_researched_rounds`, `auto_answered_rounds`, and `architect_failures`. When `deepInterview` ask metadata is present, no manual per-round write is required for the answer shell; only scoring enrichment/state maintenance remains. For scoring enrichment and state maintenance, use the native `gjc deep-interview` surface and keep every payload **incremental**: stage only the delta for the current round (`stage --for record-round` with just the one round record carrying its `round_key`; the runtime merges it into the existing transcript by durable key), only the changed facts (`--for update-facts`; facts merge losslessly by `id` — a one-fact patch never erases prior facts), or only the changed maintenance fields (`--for merge-state`). Never resend the whole `rounds` array or the full state envelope — earlier rounds are already persisted, resending them is wasteful and racy, and the merge preserves them without your copy. Optionally dry-run with `check`, then commit with `apply`; for a simple immediate update, `gjc deep-interview write --input '<json>'` is the one-shot equivalent (incremental merge; add `--reset` only when deliberately replacing state — the locked intent contract survives a reset). Ambiguity is **runtime-owned**: `apply`/`write` derive `current_ambiguity` from the latest scored round and clamp it to the deterministic floor; report the round's scores and your raw `ambiguity` on the round record, then read the effective value back from the command output (`current_ambiguity`/`result_ambiguity`) instead of hand-setting `state.current_ambiguity`. The session resolves from `GJC_SESSION_ID` automatically; exactly one draft is pending at a time, and a revision conflict at `apply` invalidates the draft with typed recovery — re-stage the same small delta against current state, never do revision arithmetic. Never patch `.gjc/_session-{sessionid}/state` directly unless an explicit force override is active.
539
+ Also recompute and persist `ambiguity_milestone` each round (detect band transitions for the Phase 3 panel), and persist `auto_answer_streak`, `refined_rounds`, `lateral_reviews`, and `lateral_panel_failures` alongside the existing fields.
540
+
541
+ #### Delta payload schemas
542
+
543
+ Every staged/write payload is one JSON object `{"state": { …delta only… }}`. Envelope lifecycle keys (`current_phase`, `active`, `skill`, `version`, `state_revision`, `receipt`, `updated_at`, `last_applied_draft_id`) are runtime-owned — if included they are stripped and reported back as `ignored_runtime_owned_keys`, never persisted. `state.intent_contract` and `state.intent_review` are recorder-owned: only the Round 0 / intent-review `ask` recorder can write them (they carry canonical digests and answer-hash bindings you cannot fabricate); a payload carrying them is stripped the same way — never hand-construct an intent contract.
544
+
545
+ **`stage --for record-round`** — exactly one round record, merged into the transcript by `round_key`:
546
+
547
+ ```json
548
+ {
549
+ "state": {
550
+ "rounds": [
551
+ {
552
+ "round": <n>,
553
+ "round_key": "<durable key from the answered shell>",
554
+ "lifecycle": "scored",
555
+ "ambiguity": <raw 0..1 score>,
556
+ "scores": { "goal": 0.9, "constraints": 0.8, "criteria": 0.9, "context": 0.85 },
557
+ "weakest_component_id": "<component id>",
558
+ "weakest_dimension": "goal|constraints|criteria|context",
559
+ "component_scores": { "<component-id>": { "goal": 0.9, "constraints": 0.8, "criteria": 0.9, "context": 0.85, "gaps": { } } },
560
+ "structured_scorer_output": { },
561
+ "ontology": { },
562
+ "ontology_stability": { }
563
+ }
564
+ ]
565
+ }
566
+ }
457
567
  ```
458
568
 
459
- `prior_effective_ambiguity` may be `null` on the first scored round; show that returned value rather than inventing a prior percentage. The transition lifecycle and round identity remain available at `<native>.native_projection.transition.lifecycle` and `<native>.native_projection.transition.round_key` for control flow, but are not progress prose.
569
+ Include only the one round being enriched; identity fields (`question_text`, `answer_hash`) already persisted on the shell never need resending — the merge preserves them and never downgrades `scored` back to `answered`.
460
570
 
461
- Apply `language.instruction` when present before showing this progress report; apply the self-proofread once (DIPP-5) to narrative status text, generated prose cells, gaps, and next-target phrasing while preserving the real native projection paths and fixed report structure.
571
+ **`stage --for update-facts`** — only the changed fact records, merged field-wise by `id`:
462
572
 
463
- ### Step 2e: Check Tiered Confirmation Cadence
573
+ ```json
574
+ {
575
+ "state": {
576
+ "established_facts": [
577
+ { "id": "<fact-id>", "statement": "<fact>", "round": <n>, "disputed": false }
578
+ ]
579
+ }
580
+ }
581
+ ```
582
+
583
+ To dispute: send `{ "id": "<fact-id>", "disputed": true }`. To supersede: send `{ "id": "<old-id>", "disputed": false, "superseded_by": "<new-id>" }` plus the new fact record. A delta can never hard-delete a fact — unaddressed facts survive verbatim, so never resend the full facts array.
584
+
585
+ **`stage --for merge-state`** — only the changed maintenance fields (shallow-merged into `state`; `null` deletes a key):
586
+
587
+ ```json
588
+ {
589
+ "state": {
590
+ "ambiguity_milestone": "<band>",
591
+ "auto_answer_streak": <n>,
592
+ "refined_rounds": [<n>],
593
+ "lateral_reviews": [ { "round": <n>, "personas": [], "findings": "<summary>" } ],
594
+ "topology": { "components": [ … ], "last_targeted_component_id": "<id>" }
595
+ }
596
+ }
597
+ ```
598
+
599
+ `topology` and other object fields replace whole — include the full object when changing any part of it; `rounds` and `established_facts` are the only keyed-merge collections.
600
+
601
+ **`write --input`** — same `{"state":{…}}` shape and same merge semantics as a staged `merge-state` apply, committed in one step. `write --reset --input` replaces the whole `state` with the payload (the locked `intent_contract` is re-attached automatically); use it only for deliberate re-initialization.
602
+
603
+ ### Step 2f: Check Tiered Confirmation Cadence
464
604
 
465
605
  Confirmation cadence is tiered by round, adopted from ouroboros's ooo interview, while the hard safety cap is retained:
466
606
 
467
607
  - **Rounds 1-3 (auto-continue)**: minimum context gathering — proceed to the next question without a "continue?" prompt.
468
- - **Rounds 4-15 (ask to continue)**: after each round, ask "Continue, or proceed with current clarity ({<native>.native_projection.effective_ambiguity}%)?" so the user controls depth.
469
- - **Rounds 16+ (diminishing-returns warning)**: keep asking "Continue?" but prefix a diminishing-returns warning: "We're at {n} rounds (ambiguity: {<native>.native_projection.effective_ambiguity}%); each further round yields less. Continue or proceed?"
608
+ - **Rounds 4-15 (ask to continue)**: after each round, ask "Continue, or proceed with current clarity ({score}%)?" so the user controls depth.
609
+ - **Rounds 16+ (diminishing-returns warning)**: keep asking "Continue?" but prefix a diminishing-returns warning: "We're at {n} rounds (ambiguity: {score}%); each further round yields less. Continue or proceed?"
470
610
  - **Round 3+ early exit**: still allow immediate exit if the user says "enough", "let's go", "build it".
471
- - **Round 100 (hard cap)**: "Maximum interview rounds reached. Proceeding with current clarity level ({<native>.native_projection.effective_ambiguity}%)." The tiered cadence never removes this hard safety cap.
611
+ - **Round 100 (hard cap)**: "Maximum interview rounds reached. Proceeding with current clarity level ({score}%)." The tiered cadence never removes this hard safety cap.
472
612
 
473
613
  ## Phase 3: Lateral Review Panel (milestone-triggered)
474
614
 
475
- The runtime returns the sole ready-first milestone mapping: `ready` when effective ambiguity is at or below the frozen threshold; otherwise `initial` above 0.60, `progress` above 0.30, and `refined` at or below 0.30. Use the returned milestone rather than recalculating bands.
615
+ The interview convenes a short multi-persona panel at **ambiguity-milestone transitions** instead of at fixed round numbers. Define milestone bands from the round's ambiguity score:
616
+
617
+ | Band | Ambiguity |
618
+ |------|-----------|
619
+ | `initial` | > 0.60 |
620
+ | `progress` | 0.60 ≥ a > 0.30 |
621
+ | `refined` | 0.30 ≥ a > threshold |
622
+ | `ready` | ≤ threshold |
476
623
 
477
624
  A transition occurs whenever the band changes versus the prior scored round — in either direction, since bidirectional scoring can move the band back up. On a transition, and also before synthesizing any agent-supplied answer (auto-research candidates, an auto-answer, or a code/brownfield auto-confirm that carries real interpretation), convene the panel before generating or asking the next question.
478
625
 
@@ -572,7 +719,7 @@ Spec structure:
572
719
  {List stable confirmed decisions promoted into `state.established_facts`, including source round, evidence, and disputed status when any fact was contradicted.}
573
720
 
574
721
  ## Trigger Metadata
575
- {Summarize per-round trigger metadata: trigger label/status, affected component/dimension, native-returned effective ambiguity transition, evidence, contradicted established fact when relevant, and disputed/unresolved rationale when applicable.}
722
+ {Summarize per-round trigger metadata: trigger label/status, affected component/dimension, prior -> new ambiguity direction, evidence, contradicted established fact when relevant, and disputed/unresolved rationale when applicable.}
576
723
 
577
724
  ## Lateral Review Panel
578
725
  {Summarize convened panels: round, milestone transition or pre-answer trigger, personas dispatched, and the concrete findings folded into questions. Note any lateral_panel_failures.}
@@ -667,10 +814,10 @@ After the spec is written, mark it `pending approval` and present execution opti
667
814
 
668
815
  ### Phase 5b: Handoff before chain
669
816
 
670
- Before invoking `/skill:ralplan`, `/skill:team`, or `/skill:ultragoal`, the final spec must already be persisted through the native deep-interview write command. For ordinary user-selected handoff, mark deep-interview ready for the skill tool's chain guard:
817
+ Before invoking `/skill:ralplan`, `/skill:team`, or `/skill:ultragoal`, the final spec must already be persisted through the native deep-interview write command (`gjc deep-interview --write --stage final …`). That command itself moves the workflow to the `handoff` phase, so no separate state write is needed for the skill tool's chain guard. Verify readiness with:
671
818
 
672
819
  ```
673
- gjc state deep-interview write --input '{"current_phase":"handoff"}' --json
820
+ gjc deep-interview read --json
674
821
  ```
675
822
 
676
823
  For a preselected deliberate ralplan path, prefer the single sanctioned bridge command instead:
@@ -715,7 +862,7 @@ Skipping any stage is possible but reduces quality assurance:
715
862
  - Use `read/search/find exploration or a bounded read-only planner/architect subagent` for brownfield codebase exploration (run BEFORE asking user about codebase)
716
863
  - Use opus model (temperature 0.1) for ambiguity scoring — consistency is critical
717
864
  - Round 0 topology confirmation happens before ambiguity scoring; Phase 2 scoring must honor locked topology and rotate targeting across active components when more than one is present
718
- - Normal interview persistence uses CLI-owned drafts: `gjc deep-interview draft create|edit|show|check|rebase|discard`, followed by the matching typed command with `--draft-id --expected-draft-revision <latest_draft_revision> --json`. All public draft commands require standalone `--json`; value-taking flags use exactly `--name value`, while `--json` and `--null` take no value, and there is no public `draft consume` command. Use `--value`, standalone `--null`, and append scaffolds for bounded payload fields: valueless append on a missing object-item array appends `{}`, valueless append on a missing scalar-item array initializes `[]`, and appending to an existing scalar-item array requires `--value` or `--value-file`. Retain each returned `draft_revision`. `check` reports a stale state base but does not mutate; explicitly `rebase` only with the caller-observed `--to-state-revision` and then check again. Inline JSON request flags are compatibility-only. Never construct a full payload or generic `gjc state write --input` envelope. Generic `gjc state` remains compatibility/recovery-only for the explicit clear and final handoff paths; never edit `.gjc/_session-{sessionid}/state` directly without force override.
865
+ - Use `gjc deep-interview write` / `gjc deep-interview read` for interview state persistence; the initial and subsequent deep-interview state payloads must include `threshold_source` alongside `threshold`; do not edit `.gjc/_session-{sessionid}/state` directly without force override. For incremental scoring/maintenance updates, prefer the staged-transition verbs (`stage --for <transition> --input '<json>'`, `check`, `apply`, `discard`) — stage only the current delta (one round record by `round_key`, changed facts, or changed fields), never the whole transcript; `write` is incremental by default and replaces only with an explicit `--reset`; the session is inherited from `GJC_SESSION_ID`, revision CAS is runtime-owned, and the effective `current_ambiguity` is derived and clamped by the CLI at `apply`/`write` — read it from the command output rather than setting it yourself.
719
866
  - Use the GJC workflow CLI to save the final spec at `.gjc/_session-{sessionid}/specs/deep-interview-{slug}.md` exactly; do not use `write`, `edit`, or `ast_edit` directly on `.gjc/` paths without force override.
720
867
  - Use public GJC workflow entrypoints to bridge to ralplan, ultragoal, or team only after explicit execution approval — never implement directly. Implementation handoff defaults to ultragoal; reserve team for when tmux-based interactive worker parallelization is genuinely required.
721
868
  - The lateral-review panel spawns read-only persona subagents (Task tool) in parallel with independent context; it is an assist layer, never an executor and never the completion authority
@@ -857,7 +1004,7 @@ Optional settings in `.gjc/settings.json`:
857
1004
 
858
1005
  ## Resume
859
1006
 
860
- If interrupted, run `/skill:deep-interview` again. Resume through `gjc deep-interview inspect --session-id <id> --selector summary --json`, then selectively inspect topology, pending shells, recent scored rounds, facts, triggers, or floor as needed; do not read or edit `.gjc/_session-{sessionid}/state` files directly unless an explicit force override is active.
1007
+ If interrupted, run `/skill:deep-interview` again. The skill resumes from GJC workflow state via `gjc deep-interview read`; do not read or edit `.gjc/_session-{sessionid}/state` files directly unless an explicit force override is active.
861
1008
 
862
1009
  ## Integration with staged team routing
863
1010