carthagent 1.0.7 → 1.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/README.md +140 -83
  2. package/bin/ctg.mjs +14 -732
  3. package/docs/beta-rewards-e2e-plan.md +48 -0
  4. package/docs/beta-rewards-e2e-results.md +84 -0
  5. package/docs/cloud-onboarding-acceptance.md +65 -0
  6. package/docs/glyph-review/host-chrome-glyph-compatibility-v4.md +83 -0
  7. package/docs/glyph-review/test-isolation-v1.md +26 -0
  8. package/docs/glyph-review/typecheck-base.log +1 -0
  9. package/docs/glyph-review/typecheck-v4.log +1 -0
  10. package/docs/glyph-review/unicode-inventory-v4.csv +402 -0
  11. package/docs/help-dispatch-review.md +69 -0
  12. package/docs/launch-readiness-live-results.md +65 -0
  13. package/docs/legacy-cli.md +150 -0
  14. package/docs/live-theme-plugin-api.md +18 -0
  15. package/docs/native-cli.md +102 -0
  16. package/docs/native-compatibility.md +16 -0
  17. package/docs/native-daily-quests.md +132 -0
  18. package/docs/native-glyph-pty.md +59 -0
  19. package/docs/native-manual-testing.md +336 -0
  20. package/docs/native-slash-acceptance-handoff.md +49 -0
  21. package/docs/native-terminal-paired-failure-2026-10-17.md +40 -0
  22. package/docs/native-terminal-performance.md +310 -0
  23. package/docs/native-terminal-semantics-evidence/README.md +25 -0
  24. package/docs/native-terminal-semantics-evidence/controlled-host-model-selftest.json +16 -0
  25. package/docs/native-terminal-semantics-evidence/current-acceptance-status.json +59 -0
  26. package/docs/native-terminal-semantics-evidence/final-binary-focused-85bb44a.json +154 -0
  27. package/docs/native-terminal-semantics-evidence/final-binary-full-incomplete-85bb44a.json +160 -0
  28. package/docs/native-terminal-semantics-evidence/final-binary-layout-85bb44a.json +149 -0
  29. package/docs/native-terminal-semantics-evidence/final-binary-layout-interactive-85bb44a.json +159 -0
  30. package/docs/native-terminal-semantics-evidence/final-binary-model-picker-escape-unchanged-85bb44a.json +44 -0
  31. package/docs/native-terminal-semantics-evidence/final-binary-model-picker-exact-identity-85bb44a.json +47 -0
  32. package/docs/native-terminal-semantics-evidence/final-binary-model-picker-unchanged-model-incomplete-85bb44a.json +58 -0
  33. package/docs/native-terminal-semantics-evidence/final-binary-model-selftest.json +16 -0
  34. package/docs/native-terminal-semantics-evidence/final-binary-picker-cancel-incomplete-85bb44a.json +62 -0
  35. package/docs/native-terminal-semantics-evidence/focused-clipboard-title-stale-binary.json +161 -0
  36. package/docs/native-terminal-semantics-evidence/layout-stale-binary-observation-not-accepted.json +153 -0
  37. package/docs/native-terminal-semantics-evidence/picker-latest-incomplete-attempt.json +62 -0
  38. package/docs/native-terminal-semantics-evidence/picker-previous-probe-pass.json +61 -0
  39. package/docs/native-terminal-semantics.md +89 -0
  40. package/docs/native-upgrade.md +175 -0
  41. package/docs/opencode-composed-source-review.md +89 -0
  42. package/docs/opencode-migration.md +225 -9
  43. package/docs/opencode-owned-runtime.md +241 -0
  44. package/docs/opencode-runtime.md +12 -0
  45. package/docs/opencode-theme-provider-proof/README.md +55 -0
  46. package/docs/opencode-theme-provider-proof/live-theme-api-base.patch +122 -0
  47. package/docs/opencode-theme-provider-proof/plugin-theme-provider.patch +107 -0
  48. package/docs/opencode-theme-provider-proof/session-ui-base.patch +1217 -0
  49. package/docs/owned-host-controls-proof.md +39 -0
  50. package/docs/owned-runtime-release-manifest.md +42 -0
  51. package/docs/owned-visual-clear-proof.md +40 -0
  52. package/docs/patches/opencode-v2.0.32-glyph-spinner-test-isolation-v1.patch +50 -0
  53. package/docs/patches/opencode-v2.0.32-glyphs.patch +3670 -0
  54. package/docs/patches/opencode-v2.0.32-help-dispatch.patch +156 -0
  55. package/docs/patches/opencode-v2.0.32-live-theme-api.patch +122 -0
  56. package/docs/patches/opencode-v2.0.32-session-ui-combined-v1.patch +5272 -0
  57. package/docs/patches/opencode-v2.0.32-session-ui-combined-v2.patch +6052 -0
  58. package/docs/patches/opencode-v2.0.32-session-ui-combined-v3.patch +8657 -0
  59. package/docs/patches/opencode-v2.0.32-session-ui-combined-v4.patch +9928 -0
  60. package/docs/patches/opencode-v2.0.32-session-ui-combined-v5.patch +13965 -0
  61. package/docs/patches/opencode-v2.0.32-session-ui.patch +5137 -0
  62. package/docs/release-notes-beta.1.md +60 -0
  63. package/docs/release-notes-beta.2.md +60 -0
  64. package/docs/release-notes-native-draft.md +73 -0
  65. package/docs/release-notes-preview.10.md +121 -0
  66. package/docs/release-notes-preview.11.md +76 -0
  67. package/docs/release-notes-preview.12.md +55 -0
  68. package/docs/release-notes-preview.13.md +68 -0
  69. package/docs/release-notes-preview.9.md +130 -0
  70. package/docs/source-preview.md +120 -0
  71. package/evaluate.mjs +28 -1
  72. package/lib/budget.mjs +1 -1
  73. package/lib/cloud/client.mjs +13 -7
  74. package/lib/codegraph.mjs +1 -1
  75. package/lib/delivery-review.mjs +19 -6
  76. package/lib/delivery.mjs +3 -2
  77. package/lib/environment.mjs +8 -0
  78. package/lib/guidance.mjs +1 -1
  79. package/lib/opencode/cli-runtime.mjs +1188 -0
  80. package/lib/opencode/cli.mjs +253 -0
  81. package/lib/opencode/credentials.mjs +63 -8
  82. package/lib/opencode/demo.mjs +53 -0
  83. package/lib/opencode/evaluation-budget-plugin/index.ts +3 -0
  84. package/lib/opencode/evaluation.mjs +32 -12
  85. package/lib/opencode/headless.mjs +22 -5
  86. package/lib/opencode/provider-policy.mjs +23 -0
  87. package/lib/opencode/review.mjs +37 -16
  88. package/lib/opencode/runtime-artifact.mjs +335 -0
  89. package/lib/opencode/runtime-github-transport.mjs +121 -0
  90. package/lib/opencode/runtime-release.json +36 -0
  91. package/lib/opencode/runtime.mjs +299 -20
  92. package/lib/opencode/service.mjs +77 -35
  93. package/lib/opencode/session-options.mjs +6 -2
  94. package/lib/opencode/update.mjs +222 -0
  95. package/lib/opencode/workspace.mjs +1 -1
  96. package/lib/planning-advice.mjs +2 -2
  97. package/lib/providers/experiential.mjs +2 -2
  98. package/lib/providers/names.mjs +1 -1
  99. package/lib/tui/framing.mjs +1 -80
  100. package/lib/tui/models.mjs +1 -1
  101. package/lib/update.mjs +10 -1
  102. package/package.json +33 -7
  103. package/plugins/carthagent/README.md +23 -0
  104. package/plugins/carthagent/src/bootstrap.ts +1 -1
  105. package/plugins/carthagent/src/daily-evidence.mjs +57 -0
  106. package/plugins/carthagent/src/daily-quests-rpc.ts +50 -0
  107. package/plugins/carthagent/src/daily-source-rpc.ts +52 -0
  108. package/plugins/carthagent/src/index.ts +71 -24
  109. package/plugins/carthagent/src/rpc.ts +51 -6
  110. package/plugins/carthagent/src/server/codegraph.ts +12 -5
  111. package/plugins/carthagent/src/server/daily-quests-rpc.ts +277 -0
  112. package/plugins/carthagent/src/server/daily-source-rpc.ts +243 -0
  113. package/plugins/carthagent/src/server/delivery.ts +227 -112
  114. package/plugins/carthagent/src/server/framing.mjs +80 -0
  115. package/plugins/carthagent/src/server/policy.ts +1 -1
  116. package/plugins/carthagent/src/server/providers.ts +65 -36
  117. package/plugins/carthagent/src/server/session-controls.ts +3 -1
  118. package/plugins/carthagent/src/server/ship-agents.ts +77 -0
  119. package/plugins/carthagent/src/server/ship-context.mjs +60 -0
  120. package/plugins/carthagent/src/server/ship-guidance.ts +41 -0
  121. package/plugins/carthagent/src/server/ship-rpc.ts +71 -0
  122. package/plugins/carthagent/src/server/voyages-rpc.ts +280 -0
  123. package/plugins/carthagent/src/testing.ts +5 -0
  124. package/plugins/carthagent/src/tui.tsx +506 -0
  125. package/plugins/carthagent/src/ui/client.ts +127 -0
  126. package/plugins/carthagent/src/ui/commands.ts +70 -0
  127. package/plugins/carthagent/src/ui/daily-editor-focus.mjs +52 -0
  128. package/plugins/carthagent/src/ui/daily-editor.mjs +4 -0
  129. package/plugins/carthagent/src/ui/daily-quests-events.mjs +18 -0
  130. package/plugins/carthagent/src/ui/daily-quests-state.mjs +218 -0
  131. package/plugins/carthagent/src/ui/daily-quests.tsx +235 -0
  132. package/plugins/carthagent/src/ui/host-state.ts +42 -0
  133. package/plugins/carthagent/src/ui/model-command.ts +32 -0
  134. package/plugins/carthagent/src/ui/native-navigation.ts +23 -0
  135. package/plugins/carthagent/src/ui/native-review.d.mts +33 -0
  136. package/plugins/carthagent/src/ui/native-review.mjs +159 -0
  137. package/plugins/carthagent/src/ui/resume-session.mjs +34 -0
  138. package/plugins/carthagent/src/ui/select-mouse.ts +17 -0
  139. package/plugins/carthagent/src/ui/session-preferences.d.mts +7 -0
  140. package/plugins/carthagent/src/ui/session-preferences.mjs +14 -0
  141. package/plugins/carthagent/src/ui/theme-provision.d.mts +3 -0
  142. package/plugins/carthagent/src/ui/theme-provision.mjs +134 -0
  143. package/plugins/carthagent/src/ui/voyages-navigation-state.mjs +56 -0
  144. package/plugins/carthagent/src/ui/voyages-navigation.tsx +131 -0
  145. package/plugins/carthagent/src/ui/voyages-state.mjs +165 -0
  146. package/plugins/carthagent/src/ui/voyages.tsx +131 -0
  147. package/plugins/carthagent/src/ui/workspace-live.ts +61 -0
  148. package/plugins/carthagent/src/ui/workspace.tsx +379 -0
  149. package/plugins/carthagent/src/voyages-rpc.ts +64 -0
  150. package/plugins/carthagent/src/workspace-rpc.ts +36 -0
  151. package/plugins/carthagent/tests/commands.test.ts +107 -0
  152. package/plugins/carthagent/tests/session-preferences.test.mjs +41 -0
  153. package/plugins/carthagent/tests/voyages-navigation.test.tsx +269 -0
  154. package/plugins/carthagent/themes/carthage.json +67 -0
  155. package/plugins/carthagent/tui.ts +26 -1
  156. package/script/ctg/build-owned-runtime.sh +166 -0
  157. package/tests/budget-engine.test.mjs +4 -3
  158. package/tests/cli.test.mjs +52 -96
  159. package/tests/cloud-client.test.mjs +2 -2
  160. package/tests/daily-evidence.test.mjs +62 -0
  161. package/tests/delivery-review.test.mjs +57 -2
  162. package/tests/delivery.test.mjs +22 -1
  163. package/tests/experiential-extension.test.mjs +2 -2
  164. package/tests/experiential.test.mjs +1 -1
  165. package/tests/fixtures/native-discovery-plugin/server.ts +15 -0
  166. package/tests/generate-owned-runtime-release.test.mjs +354 -0
  167. package/tests/installed-runtime-contract.test.mjs +43 -0
  168. package/tests/native-cli-host-smoke.mjs +457 -0
  169. package/tests/native-daily-editor-focus.test.mjs +213 -0
  170. package/tests/native-daily-editor.test.mjs +43 -0
  171. package/tests/native-daily-quests-layout.test.mjs +55 -0
  172. package/tests/native-daily-quests-rpc.test.mjs +456 -0
  173. package/tests/native-daily-quests-ui.test.mjs +778 -0
  174. package/tests/native-daily-source.test.mjs +525 -0
  175. package/tests/native-demo-ui.test.mjs +48 -0
  176. package/tests/native-evaluation-admission.test.mjs +24 -0
  177. package/tests/native-fixture-browser-cleanup.test.mjs +65 -0
  178. package/tests/native-fixture-runtime.test.mjs +111 -0
  179. package/tests/native-fixture-stop-diagnostics.test.mjs +67 -0
  180. package/tests/native-glyph-pty.test.mjs +107 -0
  181. package/tests/native-manual-projects.test.mjs +170 -0
  182. package/tests/native-model-command.test.mjs +67 -0
  183. package/tests/native-owned-runtime-env.test.mjs +140 -0
  184. package/tests/native-paired-guards.test.mjs +464 -0
  185. package/tests/native-provider-policy.test.mjs +33 -0
  186. package/tests/native-pty-invocation.test.mjs +114 -0
  187. package/tests/native-pty-runtime.test.mjs +45 -0
  188. package/tests/native-resume-session.test.mjs +46 -0
  189. package/tests/native-review-consumer.test.mjs +286 -0
  190. package/tests/native-runtime-identity.test.mjs +214 -0
  191. package/tests/native-select-mouse.test.mjs +23 -0
  192. package/tests/native-ship-guidance.test.mjs +16 -0
  193. package/tests/native-ship-parity.test.mjs +526 -0
  194. package/tests/native-ship-plan.test.mjs +85 -0
  195. package/tests/native-ship-rpc.test.mjs +83 -0
  196. package/tests/native-ui-commands.test.mjs +6 -0
  197. package/tests/native-voyages-layout.test.mjs +28 -0
  198. package/tests/native-voyages-navigation.test.mjs +169 -0
  199. package/tests/native-voyages-rpc.test.mjs +397 -0
  200. package/tests/native-voyages-ui.test.mjs +307 -0
  201. package/tests/opencode-atomic-write.test.mjs +55 -0
  202. package/tests/opencode-cli.test.mjs +1312 -0
  203. package/tests/opencode-codegraph-plugin.test.mjs +47 -0
  204. package/tests/opencode-delivery.test.mjs +16 -0
  205. package/tests/opencode-providers.test.mjs +248 -20
  206. package/tests/opencode-runtime.test.mjs +597 -8
  207. package/tests/opencode-session-controls.test.mjs +15 -0
  208. package/tests/opencode-ship-rpc.test.mjs +71 -0
  209. package/tests/opencode-update.test.mjs +475 -0
  210. package/tests/opencode-workspace.test.mjs +51 -2
  211. package/tests/owned-runtime-publish-workflow.test.mjs +477 -0
  212. package/tests/release-workflow.test.mjs +46 -0
  213. package/tests/runtime-artifact.test.mjs +269 -0
  214. package/tests/runtime-development-trust.test.mjs +231 -0
  215. package/tests/runtime-github-transport.test.mjs +132 -0
  216. package/tests/runtime-token-env.test.mjs +23 -0
  217. package/tests/server.test.mjs +3 -1
  218. package/tests/ship-telemetry.test.mjs +1 -1
  219. package/tests/source-preview.test.mjs +253 -0
  220. package/tests/test_native_terminal_probe.py +76 -0
  221. package/tests/test_native_terminal_semantics.py +232 -0
  222. package/tests/tui.test.mjs +2 -2
  223. package/tests/update.test.mjs +42 -5
  224. package/tests/verify-draft-runtime-gate.test.mjs +280 -0
  225. package/tests/verify-owned-runtime-release.test.mjs +371 -0
  226. package/tests/workspace-live.test.mjs +127 -0
  227. package/tools/benchmark/diagnose-request.mjs +59 -36
  228. package/tools/benchmark/eval-common.mjs +3 -3
  229. package/tools/benchmark/evaluators.test.mjs +4 -4
  230. package/tools/benchmark/guard.test.mjs +35 -2
  231. package/tools/benchmark/guard.ts +20 -7
  232. package/tools/benchmark/planning-startup.test.mjs +30 -34
  233. package/tools/benchmark/runner.mjs +12 -7
  234. package/tools/benchmark/runner.test.mjs +23 -7
  235. package/tools/benchmark/upstream-error.test.mjs +16 -2
  236. package/tools/generate-owned-runtime-release.mjs +217 -0
  237. package/tools/installed-runtime-contract.mjs +16 -0
  238. package/tools/manual-runtime-manifest.mjs +39 -0
  239. package/tools/native-fixture-browser-cleanup.mjs +59 -0
  240. package/tools/native-fixture-stop-diagnostics.mjs +45 -0
  241. package/tools/native-fixture.mjs +199 -40
  242. package/tools/native-glyph-helpers.py +127 -0
  243. package/tools/native-glyph-pty.py +144 -0
  244. package/tools/native-manual-projects.mjs +259 -0
  245. package/tools/native-manual.mjs +338 -0
  246. package/tools/native-model-picker-acceptance.py +306 -0
  247. package/tools/native-owned-runtime-env.sh +47 -0
  248. package/tools/native-paired-guards.mjs +282 -0
  249. package/tools/native-paired-manifest.mjs +72 -0
  250. package/tools/native-paired-orchestration.sh +51 -0
  251. package/tools/native-plugin-readiness.mjs +33 -0
  252. package/tools/native-plugin-readiness.test.mjs +53 -0
  253. package/tools/native-pty-invocation.mjs +26 -0
  254. package/tools/native-pty-runtime.mjs +83 -0
  255. package/tools/native-pty-smoke.py +147 -24
  256. package/tools/native-public-repo-shell-result.mjs +13 -0
  257. package/tools/native-public-repo-shell-result.test.mjs +28 -0
  258. package/tools/native-runtime-identity.mjs +201 -0
  259. package/tools/native-slash-acceptance-env.py +38 -0
  260. package/tools/native-terminal-semantics.py +882 -0
  261. package/tools/owned-shell-observer/index.ts +16 -0
  262. package/tools/owned-shell-observer/package.json +1 -0
  263. package/tools/owned-visual-clear-env.py +48 -0
  264. package/tools/owned-visual-clear-model.py +21 -0
  265. package/tools/pinned-owned-runtime-inputs.mjs +46 -0
  266. package/tools/prepare-native-manual.mjs +122 -0
  267. package/tools/run-native-terminal-paired.sh +403 -0
  268. package/tools/runtime-token-env.mjs +8 -0
  269. package/tools/seed-native-switch-fixture.mjs +79 -0
  270. package/tools/test-native-controls.mjs +3 -1
  271. package/tools/test-native-daily-quests.mjs +65 -0
  272. package/tools/test-native-default-cli.mjs +106 -0
  273. package/tools/test-native-delivery-host.mjs +102 -20
  274. package/tools/test-native-evaluation.mjs +7 -3
  275. package/tools/test-native-glyph-pty.mjs +94 -0
  276. package/tools/test-native-host.mjs +91 -65
  277. package/tools/test-native-outcomes.mjs +3 -1
  278. package/tools/test-native-package.mjs +206 -38
  279. package/tools/test-native-performance.mjs +26 -0
  280. package/tools/test-native-product.mjs +90 -0
  281. package/tools/test-native-pty.mjs +34 -9
  282. package/tools/test-native-public-repo.mjs +224 -0
  283. package/tools/test-native-refresh-reentry.mjs +106 -0
  284. package/tools/test-native-report.mjs +27 -20
  285. package/tools/test-native-review.mjs +75 -0
  286. package/tools/test-native-runtime.mjs +120 -0
  287. package/tools/test-native-ship-models.mjs +176 -0
  288. package/tools/test-native-ship-walkthrough.mjs +96 -0
  289. package/tools/test-native-slash-commands.mjs +125 -0
  290. package/tools/test-native-slash-commands.py +242 -0
  291. package/tools/test-native-swe-host.mjs +224 -55
  292. package/tools/test-native-tasks.mjs +77 -0
  293. package/tools/test-native-terminal-performance.py +887 -0
  294. package/tools/test-native-terminal-readiness.sh +85 -0
  295. package/tools/test-native-terminal-semantics-installed.mjs +38 -0
  296. package/tools/test-native-visual-clear-installed.mjs +48 -0
  297. package/tools/test-owned-host-controls.mjs +238 -0
  298. package/tools/test-owned-opencode-runtime.mjs +35 -0
  299. package/tools/test-owned-visual-clear-env.py +120 -0
  300. package/tools/test-owned-visual-clear.py +373 -0
  301. package/tools/verify-draft-runtime-gate.mjs +138 -0
  302. package/tools/verify-owned-runtime-release.mjs +114 -0
  303. package/tools/verify-release-version.mjs +21 -1
@@ -0,0 +1,310 @@
1
+ # Native terminal performance probe
2
+
3
+ `npm run test:native-terminal-performance` is an **opt-in**, POSIX-only check
4
+ against the package-owned OpenCode 2.0.32 executable. Set `CTG_OPENCODE_BIN`
5
+ when the executable is outside `node_modules/@opencode/cli/bin/opencode.exe`.
6
+ It starts a disposable real PTY with the Carthagent plugin enabled and prints
7
+ JSON evidence. It is deliberately not in the default CI test script because
8
+ terminal scheduling and host load make latency thresholds unsuitable as a
9
+ flaky default gate.
10
+
11
+ The first-render/plugin warmup happens before the input clock starts. Each of
12
+ 30 (minimum) literal keystrokes is timed from writing the key to observing a
13
+ new matching cell at the native editor placeholder's input origin in a parsed
14
+ VT screen. Arbitrary transcript/status text and other editor-row cells are not
15
+ accepted as an echo. This is a PTY key-to-render proxy, not a compositor/GPU
16
+ presentation timestamp. It includes the harness's PTY `select`/read, screen
17
+ parsing, and evidence-detection path. Per-sample polling and VT-feed work are
18
+ recorded as observer instrumentation; they are not subtracted or treated as a
19
+ compositor estimate. Input p95 target: 50 ms.
20
+
21
+ The JSON artifact includes run-start load average, CPU count, and host memory
22
+ availability so a loaded host is visible alongside latency samples. These
23
+ measurements remain sensitive to concurrent workloads; use an otherwise idle,
24
+ controlled host for comparisons, and do not attribute a paired delta to CTG
25
+ unless the run is actually paired/alternated on the same host window.
26
+
27
+ The harness also observes a bounded idle window (default 10 seconds, maximum
28
+ 300 seconds), captures terminal-output bytes, and reports separate process-tree
29
+ RSS for the TUI and its owned fixture server when available. Output is
30
+ informational, not a failure by itself: OpenCode's native status clock can
31
+ legitimately redraw. This brief RSS range is descriptive only. No product-defined
32
+ sustained-memory ceiling exists, and a short idle sample cannot establish a
33
+ long-term bound or absence of leaks. `--idle-seconds` and `--idle-byte-limit`
34
+ control the brief observation; `--memory-growth-limit-mb` is opt-in and only
35
+ reports comparison with an explicitly operator-approved diagnostic threshold.
36
+ It does not affect `overallTargetsMet`. `--report path.json` saves the output.
37
+
38
+ ### Workspace render acceptance and bounded-memory evidence
39
+
40
+ The native compatibility acceptance additionally requires cached `/ctg-workspace`
41
+ load within 300 ms and bounded plugin memory. The existing workspace benchmark
42
+ is RPC-only and does not establish visible TUI completion. Paired acceptance
43
+ must include a separate real-PTY `/ctg-workspace` path: resolve slash
44
+ autocomplete first, prove the command is staged in the editor and no completion
45
+ dialog is active, then anchor the start timestamp to the submission Enter write;
46
+ stop only when the command's plugin
47
+ route has opened and a required, exact workspace-render success sentinel is
48
+ parsed from the PTY. The sentinel and setup must prove a post-submit render
49
+ phase—not slash autocomplete, the old session screen, a dialog, or a blank
50
+ workspace. A missing sentinel/blank render is a hard failure with no latency
51
+ metric. Record select/read, VT-feed, parser, and detection observer durations;
52
+ report them without subtraction. The 300 ms maximum applies to the complete
53
+ Enter-to-render observation.
54
+
55
+ The strict post-submit workspace-render probe is implemented, but remains
56
+ unverified on the live UI while the workspace pane is blank/being fixed. It must
57
+ fail closed until the route and data-backed sentinel actually render.
58
+
59
+ For bounded memory release evidence, the parent has proposed—not inherited from
60
+ the original compatibility document—this explicit 30-minute offline comparison
61
+ gate: baseline and CTG each have a 5-minute warmup, followed by 25 minutes of
62
+ 1-second RSS observations; record TUI process-tree RSS and owned-server
63
+ process-tree RSS independently and combined. Proposed, reviewable calculations
64
+ use combined TUI+owned-server RSS, with each condition run serially under the
65
+ same finite replay trace: warm each condition for 5 minutes, then collect 1,500
66
+ planned one-second slots over exactly 25 minutes. Index slots from a monotonic
67
+ start (`n = 0..1499`); preserve each actual monotonic timestamp and sample
68
+ lateness. A sample later than 250 ms after its planned slot, duplicate slot,
69
+ missing process/PID, or missing sample is a failure; never substitute zero,
70
+ interpolate, drop, or pair runs by exact wall-clock timestamp. Compare matching
71
+ slot indices, not jittered timestamps. Define block 0 as slots 0..299 and the
72
+ final block as 1200..1499. Let `B0` and `C0` be the medians of combined RSS in
73
+ block 0 for baseline and CTG. For every slot define baseline-adjusted excess
74
+ growth `D[n] = (CTG[n] - C0) - (baseline[n] - B0)`. The retained-growth gate
75
+ proposal is `max(D[n]) <= 128 MiB` over all slots. The observable-plateau
76
+ proposal is `median(D[1200..1499]) - median(D[0..299]) <= 32 MiB`. Preserve raw
77
+ TUI/server/combined series, planned and actual monotonic timestamps, lateness,
78
+ host conditions, workload request/reconnect/error counts, and cleanup evidence.
79
+ RSS is a process-tree RSS proxy; summing process RSS may double-count shared
80
+ pages and is not physical unique memory.
81
+ These finite-window release criteria are engineering observations, not
82
+ mathematical long-term memory guarantees. Parent/product review must approve the
83
+ formula, workload, and failure policy before execution; this is plan review
84
+ only, not authorization to run the workload. The replay must be a finite,
85
+ checked-in deterministic sequence of loopback streaming requests with fixed
86
+ payload sizes, chunk sizes, chunk pacing, connection close/reconnect positions,
87
+ and exact request count. Baseline and CTG must replay byte-for-byte equivalent
88
+ request traces; record per-request bytes/chunks/timing and reconnect outcomes.
89
+ Any mismatch or failure,
90
+ missed sample, or threshold exceedance is reported as failure, not dropped. Do
91
+ not run beside active authors; no such timed observation is authorized here.
92
+
93
+ Warm-session-switch target is 150 ms. The opt-in `--switch-fixture` mode uses
94
+ two prepopulated OpenCode sessions in the pinned host's disposable database,
95
+ opens the actual native Open Sessions menu (`open.menu`, bound to Ctrl+O in the
96
+ isolated profile), and times Enter acceptance to the selected session's unique
97
+ persisted assistant-history marker. It visits both histories before 30
98
+ alternating samples to warm them. It excludes menu-open/search time and does
99
+ not use RPC timing. Timing is Enter write through PTY polling/read, VT parsing,
100
+ and parsed destination-marker observation—not compositor/GPU presentation.
101
+ Per-sample observer polling and parse work are reported, never subtracted.
102
+ Sessions must be in the same project because this build's
103
+ Open Sessions picker scopes session rows to the active project. Switch mode is
104
+ diagnostic-only; input p95 is not measured in that mode.
105
+
106
+ The separate `npm run test:native-performance` probe measures cached workspace
107
+ RPC only. Its samples must not be described as terminal input, session-switch,
108
+ or `/ctg-workspace` visible-render latency. The actual paired PTY benchmark must
109
+ include the strict post-submit UI-render sample described above.
110
+
111
+ ## Recorded host run (2026-10-17)
112
+
113
+ The authorized 2026-10-17 controlled-window attempt is **failed diagnostic
114
+ evidence only** (runner aggregate exit 1; no valid latency samples). Retained
115
+ artifacts are at
116
+ `/tmp/opencode/ctg-native-terminal-paired-approved-20261017T181325Z`. Its
117
+ manifest records frozen source `38ad06f7d439bc7c15b901f7b2c741b31486e93a`,
118
+ owned CLI 2.0.32, and the selected dependency identity. Both baseline passes
119
+ failed before measurement because dependency provenance attempted to resolve
120
+ the null plugin path. Both CTG passes passed raw native inventory/health checks,
121
+ then failed readiness because the detector expected `Ask anything`, while the
122
+ actual native editor hint is `Message carthagent…`. The remediation adds a
123
+ strict bounded readiness mode and actual loopback fixture script; no latency
124
+ threshold or editor-cell criterion is relaxed. Their reports are marked
125
+ failed and contain no valid input/switch sample arrays. Do not quote them as
126
+ latency evidence. Private seeder logs and fixture credentials remain only in
127
+ the mode-0700 artifact directory; do not copy them into source control.
128
+
129
+ ### Authorized non-timed readiness follow-up
130
+
131
+ On the clean product checkout `2d8efc1561f26ae40d1f29cd329a8c01c2bd4c72`
132
+ (tree `c116b9b3337f64bc70a8bc11b2eedf9478a1294a`), the explicitly authorized
133
+ upstream-CLI-only readiness diagnostic used OpenCode `2.0.32`, binary SHA-256
134
+ `489b51816a77809e841310e80c88e834c28c19ad1639e12ba8a19f08b47ab607`, and
135
+ initially matched dependency tree
136
+ `a25d9aed67019a73dcf6e8a77746a043f4b76c633bbb02184350aaaa5d22c24d`.
137
+ Baseline passed: native inventory reported Carthagent absent and the seeded
138
+ fixture session rendered; `timedSamplesRun` was false. CTG inventory/health
139
+ activation passed, but strict editor readiness failed: neither the completed
140
+ fixture session nor a separately seeded empty session produced the required
141
+ `Message carthagent…` input anchor. No keystroke echo or timing metric was
142
+ recorded. Later, while authors were active, the dependency-install hash changed
143
+ to `ed47a3314dff75ea40151544f900da80c57dcfce82356da577cecd09ba728937` (while
144
+ the lockfile and pinned CLI hash remained unchanged), so further CTG attempts
145
+ were stopped. The upstream-binary check verifies the harness fix only; it does
146
+ not establish final shipping-runtime identity or acceptance. Preserve the exact
147
+ baseline result and CTG fail-closed outcome; do not call the latter a pass.
148
+
149
+ Native fixtures now carry the shared runtime identity record separately from
150
+ the compatibility version: compatibility remains exactly `2.0.32`, while the
151
+ runtime version is matched exactly against both `server.info.version` and the
152
+ CTG health RPC. The fixture first runs the product resolver/identity API with
153
+ the same options object, then independently verifies the selected bytes and
154
+ identity through the approved shared native-test loader against the trusted
155
+ release record (`lib/opencode/runtime-release.json` or the explicit developer
156
+ path `CTG_TEST_RUNTIME_RELEASE_MANIFEST`). For explicit staging roots, the
157
+ loader verifies path/hash/provenance before the product resolver can execute
158
+ the binary. The adjacent `ctg-runtime.json` is provenance only, never a trust
159
+ source; `CTG_TEST_RUNTIME_SHA256` is passed to the verifier as an explicit
160
+ developer hash input. No owned final-runtime readiness result is claimed yet.
161
+
162
+ The runner stopped with aggregate status 1 as designed. A malformed timestamp
163
+ format in the preliminary window-recording command occurred before the runner
164
+ was invoked; identities/load were rechecked and recorded before the one
165
+ authorized attempt.
166
+
167
+ No rerun is authorized by this record. The non-timed readiness check below is
168
+ for regression validation only; another ABBA needs fresh independent review
169
+ and a new controlled quiet-window confirmation.
170
+
171
+ After a fresh review approves the readiness changes, a bounded non-timed real
172
+ integration readiness check can be invoked with the archived execution snapshot
173
+ and retained manifest (it does not run the ABBA or latency samples):
174
+
175
+ ```bash
176
+ tools/test-native-terminal-readiness.sh \
177
+ /tmp/opencode/ctg-product-integration \
178
+ /tmp/opencode/ctg-native-terminal-paired-approved-20261017T181325Z/execution-snapshot.tar \
179
+ "$HARNESS_WORKTREE" \
180
+ /tmp/opencode/ctg-product-integration/node_modules/@opencode/cli/bin/opencode.exe \
181
+ /tmp/opencode/ctg-native-terminal-paired-approved-20261017T181325Z/manifest.json \
182
+ baseline
183
+ ```
184
+
185
+ Use `ctg` instead of `baseline` to verify active plugin inventory and health.
186
+ This command starts one disposable loopback fixture and performs only a
187
+ placeholder-anchored key echo/backspace check. It is not latency or long-window
188
+ acceptance evidence, and must not be run concurrently with authors/material
189
+ workloads without the operator's permission.
190
+
191
+ Earlier input figures (140.464 ms plugin-configured and 121.098 ms plugin-
192
+ disabled) are withdrawn as invalid: the old detector could match an arbitrary
193
+ terminal character rather than a changed cell in the editor. They are not
194
+ performance evidence. A separate 94.571 ms figure was taken under heavy
195
+ concurrent CI/build/test load (roughly 90% host RAM utilization per observation)
196
+ and is not a controlled measurement. Do not infer CTG overhead from the earlier
197
+ separate plugin-enabled/disabled values. After correcting the detector to
198
+ require a changed cell at the parsed editor input origin, a new 30-key
199
+ plugin-disabled run measured **181.782 ms p95** (294.085 ms max), missing the
200
+ 50 ms target. That run was still under heavy system load (8 CPUs; start load
201
+ average 14.25/14.70/17.17; 4,130 MiB available memory; end load
202
+ 14.25/14.68/17.14; 3,708 MiB available). It is valid evidence for that loaded
203
+ host window, not a controlled baseline. Idle observation was 1 second, 121 PTY
204
+ bytes, and 7.11 MiB process-tree RSS range. A controlled paired plugin/baseline
205
+ run remains pending. A separate native switch-only run successfully recorded
206
+ 30 alternating same-project session changes. This is a diagnostic observation,
207
+ not acceptance evidence. It measured **1,025.493 ms p95**
208
+ (1,391.240 ms max), missing the unchanged 150 ms target. The host was loaded:
209
+ 8 CPUs; load 16.57/15.64/15.22 at start and 15.79/15.62/15.23 at end, with
210
+ 3,914 MiB available memory at start and 4,467 MiB at end. The switch result is
211
+ valid for that loaded host window, not a controlled acceptance measurement.
212
+ Both sessions were previsited, and unique destination history markers were
213
+ checked before and after each actual selection. A follow-up switch-only run
214
+ completed under lower, though still non-idle, load: **573.526 ms p95**
215
+ (696.095 ms max), with load 6.50/6.18/9.84 at start and 8.62/6.70/9.94 at end;
216
+ available memory was 5,587 MiB at start and 5,199 MiB at end. Both runs miss
217
+ the 150 ms target; neither is a controlled acceptance measurement. Host load
218
+ and available memory are captured at start and end in JSON.
219
+
220
+ ## Controlled paired assessment (run only in a scheduled quiet window)
221
+
222
+ Do not start while CI, builds, UI lint, native evaluations, or other material
223
+ workloads are active. The parent/operator must confirm the quiet window first.
224
+ The exact pinned executable used by the runbook is
225
+ `/tmp/opencode/ctg-product-integration/node_modules/@opencode/cli/bin/opencode.exe`;
226
+ the script refuses to fall back to `~/.opencode` or a system `opencode`.
227
+
228
+ From this worktree, after the operator confirms a quiet window and fresh review
229
+ accepts the current harness head, resolve the current integration checkout HEAD
230
+ to a full commit SHA, verify that exact source tree and physical dependency
231
+ identity have been reviewed for acceptance, then run (replace the window ID
232
+ with a unique label):
233
+
234
+ ```bash
235
+ WINDOW_ID=2026-10-17-evening # choose a unique scheduled-window label
236
+ export CTG_OPENCODE_BIN=/tmp/opencode/ctg-product-integration/node_modules/@opencode/cli/bin/opencode.exe
237
+ export CTG_SOURCE_ROOT=/tmp/opencode/ctg-product-integration
238
+ export CTG_SOURCE_COMMIT="$(git -C "$CTG_SOURCE_ROOT" rev-parse HEAD)"
239
+ test "${#CTG_SOURCE_COMMIT}" -eq 40
240
+ git -C "$CTG_SOURCE_ROOT" show -s --format='%H %T %ci %s' "$CTG_SOURCE_COMMIT"
241
+ sha256sum "$CTG_SOURCE_ROOT/package-lock.json"
242
+ export SAMPLES=30
243
+ export OUTPUT_DIR="/tmp/opencode/ctg-native-terminal-paired-${WINDOW_ID}"
244
+ bash tools/run-native-terminal-paired.sh
245
+ ```
246
+
247
+ Do not reuse a previously selected source SHA when the product branch advances.
248
+ The command resolves the exact checkout HEAD at scheduling time; record that
249
+ full SHA, tree ID, dirty status, package-lock hash, owned binary hash/version,
250
+ physical dependency-install realpath/tree hash, and generated source/execution
251
+ archive hashes from `manifest.json`. The runner verifies the committed source
252
+ lockfile against the physical install and requires `CTG_SOURCE_COMMIT` to equal
253
+ the integration checkout HEAD observed by the runner before archive creation or
254
+ fixture work. Selecting an older commit is rejected even if its package lockfile
255
+ matches. The runner executes the archived current commit plus the reviewed
256
+ harness overlay, never mutable checkout source. A source/lock/install identity
257
+ mismatch fails before fixture creation. Do not treat an older archived tree or
258
+ an old benchmark run as current product acceptance evidence.
259
+
260
+ Requirements are Bash, `setsid`, Node.js, Python 3 with POSIX `pty`, and
261
+ `@opencode/client` in the pinned integration install. The runner archives the
262
+ selected immutable source commit, verifies its lockfile against the physical
263
+ dependency install containing the selected executable, and overlays only the
264
+ reviewed harness files in a disposable `/tmp` execution snapshot. It does not
265
+ write source or dependencies into the integration checkout. Its private output
266
+ directory is mode 0700 because seeder logs contain temporary loopback
267
+ credentials. The manifest retains binary version/hash, source commit/tree and
268
+ snapshot hashes, source checkout state, lockfile hash, dependency realpath and
269
+ full install tree hash, and source/harness component hashes. The script creates
270
+ independent disposable baseline and composed-production-CTG
271
+ profiles/databases with equivalent same-project fixture sessions, a loopback-
272
+ only provider, unique persisted assistant markers, and a 36x120 PTY. Before
273
+ each TUI measurement, the raw native plugin inventory must report `carthagent` active
274
+ for CTG and absent for baseline; the report records that observed state. An
275
+ activation/setup error, incomplete source archive, or identity mismatch fails
276
+ the condition and cannot produce performance metrics. It runs
277
+ ABBA (`baseline-1`, `ctg-1`, `ctg-2`, `baseline-2`); each run visits both
278
+ destinations before its measured alternating selections. Each condition gets
279
+ at least 30 switch and 30 input samples, plus one excluded input warmup. It
280
+ records per-sample UTC and monotonic start/end times, verifies the changed
281
+ input cell and its restoration to the native empty-editor placeholder after
282
+ each backspace, verifies each unique destination marker, records select/poll,
283
+ PTY read, VT-feed and predicate-detection observer counters, and retains
284
+ failures. A failed sample stays in the artifact and prevents that condition's
285
+ target from being marked met. One-second load-average and `MemAvailable`
286
+ observations run through each sample window (including the two session warmups
287
+ and input warmup). Reports and seeder logs are retained under `OUTPUT_DIR`;
288
+ disposable profiles and local servers are cleaned up on exit.
289
+
290
+ The harness leaves the thresholds unchanged (50 ms input p95, 150 ms switch
291
+ p95). These are terminal-to-parsed-PTY-screen proxies, not compositor timing;
292
+ do not subtract observer measurements or claim such a correction. A short RSS
293
+ range remains descriptive only and is not included in overall target acceptance;
294
+ there is no product memory ceiling in this assessment. Preserve the
295
+ existing **573.526 ms p95** switch observation as a loaded-host diagnostic;
296
+ the paired run, too, is diagnostic unless the operator confirms the controlled
297
+ window and independent review accepts the evidence. Deliberate fixed waits are
298
+ outside sample clocks: up to 500 ms initial frame drain, a 50 ms maximum PTY
299
+ poll quantum while preparing the picker, 1 ms maximum poll quantum while
300
+ awaiting rendered evidence, event-driven wait for the editor to return to the
301
+ empty placeholder after backspace, and the separate 10-second post-sample idle
302
+ observation. No fixed sleep is inside a switch or key-to-screen interval; PTY
303
+ read/poll/parser overhead is inside and reported. Do not subtract that observer
304
+ work.
305
+
306
+ Estimated wall time once scheduled: roughly **5–9 minutes**, including the full
307
+ dependency-tree identity scans during setup and fixture validation, fixture
308
+ seeding and four ABBA passes (typically 35–60 seconds of timed switching/input
309
+ per pass, plus startup, session seeding, and idle observation). Allow **up to 12
310
+ minutes**; abort rather than overlap a newly started material workload.
@@ -0,0 +1,25 @@
1
+ # Native terminal semantics evidence
2
+
3
+ These are separate run records. Their `probeSha256`, source commit/dirty state,
4
+ binary path/version/SHA-256, and status fields identify exactly what each run
5
+ does and does not establish.
6
+
7
+ | Artifact | Status | Interpretation |
8
+ | --- | --- | --- |
9
+ | `controlled-host-model-selftest.json` | Model self-test pass | Parser/state-model only; not an OpenCode PTY run or native acceptance. |
10
+ | `final-binary-model-selftest.json` | Model self-test pass | Repeated model-only parser/state self-test recorded alongside this evidence set; not native acceptance. |
11
+ | `picker-previous-probe-pass.json` | Picker pass | Earlier picker Escape, restored composer, zero pre-prompt requests; retained without rerun. |
12
+ | `focused-clipboard-title-stale-binary.json` | Stale-binary observation | Selection/copy readbacks passed in the controlled host model, but binary `30a3bb65…` predates the final title patch. Do not use its title pass as acceptance evidence. Physical clipboard is not verified. |
13
+ | `layout-stale-binary-observation-not-accepted.json` | Incomplete | Reports a 40x12 render pass on the same stale binary, but clipboard checks did not run and title acceptance is superseded. Not the requested final-binary layout result. |
14
+ | `picker-latest-incomplete-attempt.json` | Incomplete attempt | Later picker invocation did not establish picker dismissal; it does not revoke the separately recorded earlier picker pass. |
15
+ | `final-binary-focused-85bb44a.json` | Focused native passes | Exact selected-substring and `/copy` payload/readbacks in the modeled OSC 52 host, exact prompt transport, and title restoration against the supplied final binary. This is not physical clipboard proof. |
16
+ | `final-binary-full-incomplete-85bb44a.json` | Incomplete | Full run on the supplied binary passed picker Escape, 40x12 layout, 18,047-byte Unicode paste, `/copy`, and title restoration, but its selection attempt did not produce an OSC 52 update. The focused rerun did. |
17
+ | `final-binary-layout-85bb44a.json` | Layout pass | Independent 40x12 render pass; selection and copy were intentionally not exercised in this lane. |
18
+ | `final-binary-layout-interactive-85bb44a.json` | Interactive narrow-layout pass | At 40x12, typed unique input, backspaced one character, opened and navigated the recent-sessions menu, cancelled with Escape, and verified the edited composer input returned. Not a model-picker test. |
19
+ | `final-binary-model-picker-unchanged-model-incomplete-85bb44a.json` | Incomplete / fail | The actual model picker was visible, but the harness did not establish navigation followed by Escape dismissal and unchanged state. Later request model names alone are not accepted as picker-state evidence. |
20
+ | `final-binary-model-picker-escape-unchanged-85bb44a.json` | Bounded native model-picker pass | Opens the actual model picker with two offline options, verifies A is current, ArrowDown changes rendered selection styling to B, two Escape presses (first clears filter, second dismisses) close the dialog, no provider request occurs during cancellation, session metadata retains A, and a unique subsequent prompt reaches the fixture using model A. Physical clipboard is not tested. |
21
+ | `final-binary-model-picker-exact-identity-85bb44a.json` | Bounded native model-picker pass with strict runtime preflight | Focused rerun after probe hardening: required exact version and independently supplied expected SHA-256 are checked before `--version`/TUI execution; ArrowDown must move the captured selected styling from A to B; footer evidence is accurately named as a rendered active-session model label, and the post-cancel loopback request uses A. The earlier bounded evidence is preserved unchanged. |
22
+ | `final-binary-picker-cancel-incomplete-85bb44a.json` | Incomplete | Standalone picker run did not identify a picker screen. The corrected full run did observe and pass Escape dismissal. |
23
+ | `current-acceptance-status.json` | Bounded multi-run acceptance | Summarizes only checks observed on the exact supplied binary; physical OS clipboard remains unverified. |
24
+
25
+ The supplied binary was `/tmp/opencode/ctg-final-runtime-build/resume-build/packages/cli/dist-ctg/cli-linux-x64/bin/opencode`, version `opencode v0.0.0-ctg.2.0.32`, SHA-256 `85bb44a65e8c185f4f33d41507d29acc77f2db0cdcb0103a14476021c8e43794`. Its adjacent package manifest identifies `@opencode/cli-linux-x64` version `0.0.0-ctg.2.0.32`. Evidence is split across runs because the full-run selection gesture was not stable. Treat the combined status as bounded PTY/model acceptance only; never infer physical OS clipboard acceptance from captured OSC 52 or the controlled host model.
@@ -0,0 +1,16 @@
1
+ {
2
+ "status": "MODEL_SELFTEST_PASS_NOT_NATIVE_ACCEPTANCE",
3
+ "scope": "parser/state-model self-test only; does not launch OpenCode or exercise native PTY input",
4
+ "nativeAcceptance": "NOT_RUN",
5
+ "physicalOSClipboardVerified": false,
6
+ "seedClipboardPreservedOnInvalidPayloads": true,
7
+ "invalidPayloadsRejected": 3,
8
+ "exactSelectionRoundTrip": "SNIP",
9
+ "exactLatestCopyRoundTrip": "FINAL[SNIP]END",
10
+ "clipboardQueries": 2,
11
+ "titleRestoredFromStack": "CTG-ORIGINAL-TITLE",
12
+ "titleSaveRestoreOrder": [
13
+ "save",
14
+ "restore"
15
+ ]
16
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "status": "BOUNDED_MULTI_RUN_PASS_PHYSICAL_CLIPBOARD_UNVERIFIED",
3
+ "generatedAtUtc": "2026-10-17",
4
+ "sourceCommit": "1a79b489ba9f287efc03cf2c580ade546d0c9140",
5
+ "workingTreeDirtyAtEvidenceCapture": true,
6
+ "harnessSourceSha256AtEvidenceCapture": "f35acbcd8e506a32c0ee5240b3cd53be34fe551c7166e3327017c69ab2a57809",
7
+ "finalAuthorBinary": {
8
+ "path": "/tmp/opencode/ctg-final-runtime-build/resume-build/packages/cli/dist-ctg/cli-linux-x64/bin/opencode",
9
+ "version": "opencode v0.0.0-ctg.2.0.32",
10
+ "packageManifest": "/tmp/opencode/ctg-final-runtime-build/resume-build/packages/cli/dist-ctg/cli-linux-x64/package.json",
11
+ "packageVersion": "0.0.0-ctg.2.0.32",
12
+ "sha256": "85bb44a65e8c185f4f33d41507d29acc77f2db0cdcb0103a14476021c8e43794",
13
+ "status": "IDENTIFIED_AND_TESTED"
14
+ },
15
+ "checks": {
16
+ "controlledHostModelSelfTest": {
17
+ "status": "PASS",
18
+ "scope": "parser/state-model only; not native acceptance"
19
+ },
20
+ "pickerEscapeCancel": {
21
+ "status": "PASS",
22
+ "evidence": "final-binary-full-incomplete-85bb44a.json",
23
+ "note": "Exact supplied binary: Ctrl+O recent-sessions menu observed, Escape dismissed it, home composer restored, and zero provider requests occurred before prompt acceptance."
24
+ },
25
+ "narrowLayout": {
26
+ "status": "PASS",
27
+ "evidence": ["final-binary-full-incomplete-85bb44a.json", "final-binary-layout-85bb44a.json"],
28
+ "note": "Exact supplied binary rendered fixture response and composer in the actual 40x12 PTY; an additional interactive pass typed unique input, backspaced one character, opened the recent-sessions menu, navigated, cancelled with Escape, and verified the edited input returned in the composer. See final-binary-layout-interactive-85bb44a.json."
29
+ },
30
+ "selectionClipboard": {
31
+ "status": "PASS_CONTROLLED_HOST_MODEL",
32
+ "evidence": "final-binary-focused-85bb44a.json",
33
+ "note": "Focused run sent a real SGR drag over exactly SNIP and the modeled host accepted and queried exactly SNIP. Full-run selection was unstable and incomplete. Physical OS clipboard is not verified."
34
+ },
35
+ "clipboardOSC52": {
36
+ "status": "PASS_CONTROLLED_HOST_MODEL",
37
+ "evidence": "final-binary-focused-85bb44a.json",
38
+ "note": "Distinct /copy action emitted exactly FINAL[SNIP]END and the modeled OSC 52 host query returned the same value. This is not physical OS clipboard verification."
39
+ },
40
+ "terminalTitleRestoration": {
41
+ "status": "PASS_CONTROLLED_HOST_MODEL",
42
+ "evidence": ["final-binary-focused-85bb44a.json", "final-binary-full-incomplete-85bb44a.json"],
43
+ "note": "Exact supplied binary: ordered 22;0 save / 23;0 restore, seeded modeled title restored, PTY drained to EOF, normal exit code 0, no forced termination."
44
+ }
45
+ },
46
+ "modelPickerNavigationAndEscapeUnchangedModel": {
47
+ "status": "PASS_BOUNDED",
48
+ "evidence": "final-binary-model-picker-exact-identity-85bb44a.json",
49
+ "note": "Native model picker presented offline A/B options; current A was visible, ArrowDown moved the captured selected styling from A to B, first Escape cleared the active filter and second Escape dismissed the dialog, no provider request occurred during cancel, the rendered active-session model label still showed A, and a unique subsequent prompt used fixture model A. The rerun required an exact expected version and independently supplied SHA-256 checked before binary execution. Earlier failed attempt is retained separately and superseded only for this lane."
50
+ },
51
+ "recentSessionsMenuEscapeAndComposerRestoration": {
52
+ "status": "PASS",
53
+ "evidence": ["final-binary-full-incomplete-85bb44a.json", "final-binary-layout-interactive-85bb44a.json"],
54
+ "note": "Distinct from model-picker acceptance; the recent-sessions menu was opened, navigated, and cancelled, restoring the composer."
55
+ },
56
+ "physicalOSClipboardVerified": false,
57
+ "paidProviderTraffic": false,
58
+ "runCaveat": "Results are bounded across separate runs, not one all-green invocation. The full run's native selection gesture remains incomplete; a focused run established the selection clipboard round trip only in the controlled host model. The earlier model-picker attempt remains retained as incomplete, while the newer focused offline A/B model-picker probe passed navigation, Escape dismissal, and unchanged-model verification for that lane. Ctrl+O recent-sessions cancellation is separate from model-picker acceptance. No physical OS clipboard claim is made."
59
+ }
@@ -0,0 +1,154 @@
1
+ {
2
+ "startedAtUtc": "2026-10-17T18:53:26.105472+00:00",
3
+ "case": "focused-host-roundtrip",
4
+ "binary": "/tmp/opencode/ctg-final-runtime-build/resume-build/packages/cli/dist-ctg/cli-linux-x64/bin/opencode",
5
+ "binaryResolvedPath": "/tmp/opencode/ctg-final-runtime-build/resume-build/packages/cli/dist-ctg/cli-linux-x64/bin/opencode",
6
+ "binarySha256": "85bb44a65e8c185f4f33d41507d29acc77f2db0cdcb0103a14476021c8e43794",
7
+ "buildHash": "85bb44a65e8c185f4f33d41507d29acc77f2db0cdcb0103a14476021c8e43794",
8
+ "binaryVersion": "opencode v0.0.0-ctg.2.0.32",
9
+ "probeSha256": "f35acbcd8e506a32c0ee5240b3cd53be34fe551c7166e3327017c69ab2a57809",
10
+ "pluginSha256": "f162e6184bcb7980c7ec61e3c5c675563351aa814127cbb0a7fa1b6f79f116e6",
11
+ "sourceCommit": "1a79b489ba9f287efc03cf2c580ade546d0c9140",
12
+ "workingTreeDirty": true,
13
+ "sourceStatus": "M tools/native-terminal-semantics.py",
14
+ "sourceTreeSha256": "117be09476e05d5b2714a2d2cdbe299074b95c272d76b045246ee1bde67259ee",
15
+ "sourceDiffDirty": true,
16
+ "provider": "loopback offline fixture",
17
+ "terminal": {
18
+ "initialRows": 32,
19
+ "initialColumns": 100,
20
+ "resizeRows": null,
21
+ "resizeColumns": null,
22
+ "TERM": "xterm-256color"
23
+ },
24
+ "controlledHostClipboardModel": true,
25
+ "physicalOSClipboardVerified": false,
26
+ "checks": {
27
+ "focusedPromptTransport": {
28
+ "status": "PASS",
29
+ "exactProviderUserMessage": true,
30
+ "providerRequests": 2
31
+ },
32
+ "pickerEscapeCancel": {
33
+ "status": "NOT_RUN",
34
+ "reason": "focused terminal-host case intentionally skips picker scenario"
35
+ },
36
+ "narrowLayout": {
37
+ "status": "NOT_RUN",
38
+ "reason": "focused terminal-host case intentionally skips resize scenario"
39
+ },
40
+ "terminalTitleRestoration": {
41
+ "status": "PASS",
42
+ "reason": "Controlled terminal host restored the seeded original title after normal TUI exit",
43
+ "controlledHostModel": true,
44
+ "normalExitCode": 0,
45
+ "exitActions": [
46
+ "ctrl-u+quit+enter",
47
+ "enter",
48
+ "ctrl-c"
49
+ ],
50
+ "forcedTerminationAfterExitRequestTimeout": false,
51
+ "ptyDrainedToEof": true,
52
+ "titleSaveControls": 1,
53
+ "titleRestoreControls": 1,
54
+ "titleControlOrder": [
55
+ "save",
56
+ "restore"
57
+ ],
58
+ "modeledTitleStackDepth": 0,
59
+ "titleControlsObserved": [
60
+ "save",
61
+ "restore"
62
+ ],
63
+ "titleControlSequences": [
64
+ "22;0",
65
+ "23;0"
66
+ ],
67
+ "initialTitle": "CTG-ORIGINAL-TITLE",
68
+ "finalTitle": "CTG-ORIGINAL-TITLE",
69
+ "titleSequenceObserved": [
70
+ "OpenCode",
71
+ "OpenCode",
72
+ "OpenCode",
73
+ "OC | FINAL[SNIP]END",
74
+ "OC | FINAL[SNIP]END",
75
+ "",
76
+ "",
77
+ "CTG-ORIGINAL-TITLE"
78
+ ],
79
+ "oscTitleUpdates": [
80
+ {
81
+ "kind": "0",
82
+ "title": "OpenCode"
83
+ },
84
+ {
85
+ "kind": "0",
86
+ "title": "OpenCode"
87
+ },
88
+ {
89
+ "kind": "0",
90
+ "title": "OpenCode"
91
+ },
92
+ {
93
+ "kind": "0",
94
+ "title": "OC | FINAL[SNIP]END"
95
+ },
96
+ {
97
+ "kind": "0",
98
+ "title": "OC | FINAL[SNIP]END"
99
+ },
100
+ {
101
+ "kind": "0",
102
+ "title": ""
103
+ },
104
+ {
105
+ "kind": "0",
106
+ "title": ""
107
+ }
108
+ ]
109
+ },
110
+ "selectionClipboard": {
111
+ "status": "PASS",
112
+ "reason": "Controlled host model accepted and queried OSC 52 containing only the exact selected substring; this is not physical OS clipboard proof",
113
+ "mouseReporting": true,
114
+ "mouseDragSent": true,
115
+ "fixtureResponseInCapturedPty": true,
116
+ "fixtureResponseInScreenModel": true,
117
+ "screenExcerpt": "┃ ┃\n ┃\n\n FINALSNIPEND\n\n Build · Offline fixture · 148ms\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n ┃\n ┃ ▄\n █▀▀█ █▀▀█ █▀▀█ █▀▀▄ █▀▀▀ █▀▀█ █▀▀█ █▀▀█\n █ █ █ █ █▀▀▀ █ █ █ █ █ █ █ █▀▀▀ure\n ▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n /tmp/ctg-terminal-semantics-q7138olm/project shift+tab agents ctrl+p commands\n Continue opencode -s ses_eb4c9bb07ffe8tsXQXgmEBqYF4",
118
+ "selectedSubstring": "SNIP",
119
+ "mouseCoordinates": {
120
+ "startColumn": 11,
121
+ "endColumn": 14,
122
+ "row": 7,
123
+ "screenLine": " FINALSNIPEND",
124
+ "coordinateBasis": "1-based displayed terminal cells"
125
+ },
126
+ "controlledHostClipboardUpdates": [
127
+ "SNIP"
128
+ ],
129
+ "clipboardUpdateDeltaBeforeCopy": [
130
+ "SNIP"
131
+ ],
132
+ "controlledHostClipboardReadback": "SNIP",
133
+ "physicalOSClipboardVerified": false
134
+ },
135
+ "clipboardOSC52": {
136
+ "status": "PASS",
137
+ "reason": "Controlled host model accepted and queried OSC 52 with the exact distinct latest fixture response; this is not physical OS clipboard proof",
138
+ "copyActionSent": true,
139
+ "controlledHostClipboardUpdates": [
140
+ "FINAL[SNIP]END"
141
+ ],
142
+ "clipboardUpdateDeltaAfterSelection": [
143
+ "FINAL[SNIP]END"
144
+ ],
145
+ "controlledHostClipboardReadback": "FINAL[SNIP]END",
146
+ "physicalOSClipboardVerified": false
147
+ }
148
+ },
149
+ "status": "INCOMPLETE",
150
+ "incompleteChecks": [
151
+ "pickerEscapeCancel",
152
+ "narrowLayout"
153
+ ]
154
+ }