ibex 0.2.0 → 0.3.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 (437) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +95 -272
  3. data/docs/architecture.md +187 -35
  4. data/docs/bison-import.md +103 -0
  5. data/docs/comparison-policy.md +127 -0
  6. data/docs/configuration-model.md +59 -0
  7. data/docs/configuration-report.md +28 -0
  8. data/docs/conflict-explanation-reviews/v1/records/README.md +28 -0
  9. data/docs/conflict-explanation-study.md +62 -0
  10. data/docs/construction-profiling.md +157 -0
  11. data/docs/cst-migration.md +3 -4
  12. data/docs/cst.md +24 -0
  13. data/docs/decisions/0000-template.md +24 -0
  14. data/docs/decisions/0001-separate-ir-pipeline.md +34 -0
  15. data/docs/decisions/0002-opaque-user-code-boundary.md +32 -0
  16. data/docs/decisions/0003-self-hosted-grammar-frontend.md +32 -0
  17. data/docs/decisions/0004-shared-semantic-and-lossless-source-model.md +33 -0
  18. data/docs/decisions/0005-contained-grammar-composition.md +34 -0
  19. data/docs/decisions/0006-bounded-structural-grammar-lowering.md +32 -0
  20. data/docs/decisions/0007-shared-parser-construction-pipeline.md +33 -0
  21. data/docs/decisions/0008-versioned-runtime-package-boundary.md +36 -0
  22. data/docs/decisions/0009-isolated-parser-sessions.md +34 -0
  23. data/docs/decisions/0010-committed-runtime-observation.md +34 -0
  24. data/docs/decisions/0011-versioned-semantic-action-boundary.md +37 -0
  25. data/docs/decisions/0012-bounded-nonexecuting-analysis.md +37 -0
  26. data/docs/decisions/0013-transactional-generation-publication.md +37 -0
  27. data/docs/decisions/0014-versioned-generated-lexer.md +35 -0
  28. data/docs/decisions/0015-worker-isolated-browser-analysis.md +32 -0
  29. data/docs/decisions/0016-red-green-concrete-syntax.md +34 -0
  30. data/docs/decisions/0017-persistent-syntax-artifacts.md +35 -0
  31. data/docs/decisions/0018-conservative-incremental-syntax-reuse.md +38 -0
  32. data/docs/decisions/0019-runtime-syntax-session-boundary.md +51 -0
  33. data/docs/decisions/0020-grammar-ir-parser-contract.md +65 -0
  34. data/docs/decisions/0021-data-only-parser-table-sidecar.md +50 -0
  35. data/docs/decisions/0022-manifest-bound-verification-report.md +77 -0
  36. data/docs/decisions/0023-syntax-only-repair-results.md +48 -0
  37. data/docs/decisions/0024-direct-ielr-construction.md +42 -0
  38. data/docs/decisions/README.md +74 -0
  39. data/docs/declarative-configuration.md +262 -0
  40. data/docs/development.md +179 -2
  41. data/docs/direct-ielr-decision.md +120 -0
  42. data/docs/direct-multi-entry-decision.md +82 -0
  43. data/docs/editor-setup.md +2 -1
  44. data/docs/error-ux-review-rubric-v1.md +117 -0
  45. data/docs/error-ux-reviews/v1/records/README.md +22 -0
  46. data/docs/error-ux-round2-review-status-v1.json +27 -0
  47. data/docs/error-ux-round2-reviews/v1/records/README.md +30 -0
  48. data/docs/error-ux-round2-v1.json +1581 -0
  49. data/docs/error-ux-round2.md +111 -0
  50. data/docs/error-ux.md +54 -0
  51. data/docs/getting-started.md +80 -0
  52. data/docs/grammar-reference.md +184 -13
  53. data/docs/ielr-design.md +43 -0
  54. data/docs/ielr.md +92 -0
  55. data/docs/ja/bison-import.md +51 -0
  56. data/docs/ja/stable-api.md +53 -0
  57. data/docs/lexer-construction-profile.md +109 -0
  58. data/docs/lexer-migration.md +5 -0
  59. data/docs/maturity.md +128 -0
  60. data/docs/project-site-strategy.md +54 -0
  61. data/docs/racc-migration-evidence.md +45 -0
  62. data/docs/racc-migration.md +11 -0
  63. data/docs/release-readiness.md +126 -68
  64. data/docs/repair-semantics.md +123 -0
  65. data/docs/runtime-abi-evolution.md +307 -0
  66. data/docs/stability.md +144 -34
  67. data/docs/status.md +43 -0
  68. data/docs/syntax-sessions.md +183 -0
  69. data/docs/table-artifact.md +125 -0
  70. data/docs/test-interactions.md +219 -0
  71. data/docs/verification-report.md +137 -0
  72. data/docs/verifier-trust-boundary.md +199 -0
  73. data/docs/workloads.md +132 -0
  74. data/lib/ibex/analysis/digraph.rb +128 -0
  75. data/lib/ibex/analysis.rb +1 -0
  76. data/lib/ibex/bison_import/importer.rb +516 -0
  77. data/lib/ibex/bison_import/tokenizer.rb +260 -0
  78. data/lib/ibex/bison_import.rb +200 -0
  79. data/lib/ibex/bounded_subprocess.rb +171 -0
  80. data/lib/ibex/cli/ambiguity.rb +14 -5
  81. data/lib/ibex/cli/analysis.rb +134 -0
  82. data/lib/ibex/cli/bison_import.rb +121 -0
  83. data/lib/ibex/cli/config.rb +128 -0
  84. data/lib/ibex/cli/diagnostics.rb +31 -11
  85. data/lib/ibex/cli/documentation.rb +11 -8
  86. data/lib/ibex/cli/equiv.rb +169 -0
  87. data/lib/ibex/cli/error_messages.rb +11 -4
  88. data/lib/ibex/cli/explain.rb +14 -5
  89. data/lib/ibex/cli/fix.rb +203 -0
  90. data/lib/ibex/cli/formatting.rb +11 -10
  91. data/lib/ibex/cli/fuzz.rb +200 -0
  92. data/lib/ibex/cli/fuzz_regressions.rb +145 -0
  93. data/lib/ibex/cli/generation_artifacts.rb +53 -2
  94. data/lib/ibex/cli/generation_error_messages.rb +1 -1
  95. data/lib/ibex/cli/grammar_tests.rb +32 -14
  96. data/lib/ibex/cli/ir_tools.rb +5 -61
  97. data/lib/ibex/cli/outputs.rb +60 -33
  98. data/lib/ibex/cli/reduce.rb +202 -0
  99. data/lib/ibex/cli/reduce_reporting.rb +71 -0
  100. data/lib/ibex/cli/samples.rb +49 -23
  101. data/lib/ibex/cli/verify.rb +116 -0
  102. data/lib/ibex/cli/watch.rb +6 -5
  103. data/lib/ibex/cli.rb +357 -56
  104. data/lib/ibex/codegen/action_locations.rb +1 -1
  105. data/lib/ibex/codegen/action_method_source.rb +5 -6
  106. data/lib/ibex/codegen/action_source.rb +3 -2
  107. data/lib/ibex/codegen/ambiguity.rb +5 -4
  108. data/lib/ibex/codegen/explain.rb +123 -55
  109. data/lib/ibex/codegen/generated_action_abi.rb +10 -5
  110. data/lib/ibex/codegen/rbs.rb +15 -7
  111. data/lib/ibex/codegen/report.rb +25 -13
  112. data/lib/ibex/codegen/ruby.rb +28 -64
  113. data/lib/ibex/codegen/ruby_actions.rb +9 -6
  114. data/lib/ibex/codegen/ruby_syntax.rb +15 -9
  115. data/lib/ibex/configuration/analysis_grammar.rb +35 -0
  116. data/lib/ibex/configuration/explanation.rb +421 -0
  117. data/lib/ibex/configuration/inspector.rb +232 -0
  118. data/lib/ibex/configuration.rb +580 -0
  119. data/lib/ibex/coverage/collector.rb +21 -11
  120. data/lib/ibex/coverage/event_stream.rb +13 -7
  121. data/lib/ibex/coverage/report.rb +26 -18
  122. data/lib/ibex/coverage/runtime_event_validator.rb +30 -21
  123. data/lib/ibex/delta_reducer.rb +99 -0
  124. data/lib/ibex/diff.rb +140 -0
  125. data/lib/ibex/equiv/machine.rb +135 -0
  126. data/lib/ibex/equiv.rb +373 -0
  127. data/lib/ibex/fix.rb +557 -0
  128. data/lib/ibex/frontend/ast.rb +22 -2
  129. data/lib/ibex/frontend/bootstrap_parser.rb +6 -13
  130. data/lib/ibex/frontend/diagnostic.rb +1 -1
  131. data/lib/ibex/frontend/formatter.rb +72 -26
  132. data/lib/ibex/frontend/generated_parser.rb +147 -117
  133. data/lib/ibex/frontend/generated_parser_base.rb +7 -3
  134. data/lib/ibex/frontend/generated_parser_includes.rb +1 -11
  135. data/lib/ibex/frontend/generation.rb +1 -1
  136. data/lib/ibex/frontend/parser/declarations.rb +17 -2
  137. data/lib/ibex/frontend/parser_configuration_support.rb +56 -0
  138. data/lib/ibex/frontend/regenerator.rb +1 -0
  139. data/lib/ibex/frontend/resolution.rb +2 -1
  140. data/lib/ibex/frontend/resolver.rb +1 -1
  141. data/lib/ibex/frontend/rule_documentation.rb +2 -1
  142. data/lib/ibex/frontend/source_cursor.rb +2 -2
  143. data/lib/ibex/frontend/source_span.rb +9 -1
  144. data/lib/ibex/frontend/token_adapter/declaration_state.rb +38 -6
  145. data/lib/ibex/frontend/token_adapter.rb +10 -0
  146. data/lib/ibex/frontend.rb +1 -0
  147. data/lib/ibex/fuzz.rb +219 -0
  148. data/lib/ibex/generation_input.rb +1 -1
  149. data/lib/ibex/generation_manifest.rb +36 -25
  150. data/lib/ibex/generation_transaction.rb +1 -1
  151. data/lib/ibex/generation_transaction_recovery.rb +4 -4
  152. data/lib/ibex/generation_transaction_validation.rb +2 -2
  153. data/lib/ibex/grammar_tests.rb +1 -1
  154. data/lib/ibex/ir/automaton_ir.rb +61 -19
  155. data/lib/ibex/ir/grammar_ir.rb +76 -45
  156. data/lib/ibex/ir/lexer_ir.rb +5 -5
  157. data/lib/ibex/ir/parser_contract.rb +135 -0
  158. data/lib/ibex/ir/serialize.rb +203 -76
  159. data/lib/ibex/ir/validator/automaton.rb +64 -34
  160. data/lib/ibex/ir/validator/base.rb +51 -33
  161. data/lib/ibex/ir/validator/grammar.rb +113 -83
  162. data/lib/ibex/ir/validator/lexer.rb +2 -2
  163. data/lib/ibex/ir/validator.rb +2 -1
  164. data/lib/ibex/ir.rb +16 -3
  165. data/lib/ibex/lalr/build_metrics.rb +50 -2
  166. data/lib/ibex/lalr/builder.rb +191 -56
  167. data/lib/ibex/lalr/conflict_search.rb +15 -4
  168. data/lib/ibex/lalr/counterexample.rb +19 -14
  169. data/lib/ibex/lalr/direct_lookaheads.rb +110 -57
  170. data/lib/ibex/lalr/goto_follows.rb +229 -0
  171. data/lib/ibex/lalr/ielr/annotator.rb +214 -0
  172. data/lib/ibex/lalr/ielr/bits.rb +28 -0
  173. data/lib/ibex/lalr/ielr/inadequacy.rb +47 -0
  174. data/lib/ibex/lalr/ielr/item_lookaheads.rb +78 -0
  175. data/lib/ibex/lalr/ielr/pipeline.rb +75 -0
  176. data/lib/ibex/lalr/ielr/split_stability.rb +78 -0
  177. data/lib/ibex/lalr/ielr/split_state.rb +20 -0
  178. data/lib/ibex/lalr/ielr/state_splitter.rb +258 -0
  179. data/lib/ibex/lalr/ielr_partition.rb +22 -8
  180. data/lib/ibex/lalr/inadequacy_report.rb +50 -0
  181. data/lib/ibex/lalr/lookahead_propagation.rb +111 -0
  182. data/lib/ibex/lalr/lr0_collection.rb +121 -0
  183. data/lib/ibex/lalr/unreachable_states.rb +80 -0
  184. data/lib/ibex/lalr.rb +52 -1
  185. data/lib/ibex/location.rb +3 -3
  186. data/lib/ibex/lsp/document_handlers.rb +9 -7
  187. data/lib/ibex/lsp/initialization_handlers.rb +9 -7
  188. data/lib/ibex/lsp/navigation_handlers.rb +25 -11
  189. data/lib/ibex/lsp/parser_configuration_assistance.rb +149 -0
  190. data/lib/ibex/lsp/position_codec.rb +6 -2
  191. data/lib/ibex/lsp/request_handlers.rb +3 -2
  192. data/lib/ibex/lsp/request_support.rb +14 -7
  193. data/lib/ibex/lsp/server.rb +13 -11
  194. data/lib/ibex/lsp/symbol_index.rb +13 -13
  195. data/lib/ibex/lsp/symbol_index_builder.rb +30 -20
  196. data/lib/ibex/lsp/symbol_occurrence.rb +8 -2
  197. data/lib/ibex/lsp/transport.rb +13 -3
  198. data/lib/ibex/lsp/workspace.rb +5 -4
  199. data/lib/ibex/lsp/workspace_analyzer.rb +1 -1
  200. data/lib/ibex/lsp.rb +1 -0
  201. data/lib/ibex/messages/en.yml +28 -0
  202. data/lib/ibex/messages/ja.yml +28 -0
  203. data/lib/ibex/messages.rb +68 -0
  204. data/lib/ibex/metrics.rb +175 -0
  205. data/lib/ibex/normalize/declarations.rb +2 -0
  206. data/lib/ibex/normalize/diagnostics.rb +63 -38
  207. data/lib/ibex/normalize/expander.rb +5 -4
  208. data/lib/ibex/normalize/expression.rb +8 -6
  209. data/lib/ibex/normalize/grammar_builder.rb +26 -0
  210. data/lib/ibex/normalize/inline_expansion.rb +100 -49
  211. data/lib/ibex/normalize/lexer.rb +3 -3
  212. data/lib/ibex/normalize/parameter_ebnf_lowering.rb +11 -10
  213. data/lib/ibex/normalize/parameter_lowering.rb +40 -23
  214. data/lib/ibex/normalize/parameters.rb +31 -4
  215. data/lib/ibex/normalize/parser_configuration.rb +70 -0
  216. data/lib/ibex/normalize.rb +10 -20
  217. data/lib/ibex/racc_migration/report.rb +6 -3
  218. data/lib/ibex/rake_task.rb +1 -1
  219. data/lib/ibex/samples.rb +43 -13
  220. data/lib/ibex/table_artifact/builder.rb +266 -0
  221. data/lib/ibex/table_artifact/cst_projection.rb +70 -0
  222. data/lib/ibex/table_artifact/document.rb +39 -0
  223. data/lib/ibex/table_artifact/executor.rb +187 -0
  224. data/lib/ibex/table_artifact/serializer.rb +57 -0
  225. data/lib/ibex/table_artifact/validator/metadata.rb +179 -0
  226. data/lib/ibex/table_artifact/validator/support.rb +86 -0
  227. data/lib/ibex/table_artifact/validator/tables.rb +238 -0
  228. data/lib/ibex/table_artifact/validator.rb +253 -0
  229. data/lib/ibex/table_artifact.rb +88 -0
  230. data/lib/ibex/table_simulation/result.rb +6 -2
  231. data/lib/ibex/table_simulation/step.rb +3 -1
  232. data/lib/ibex/tables.rb +14 -0
  233. data/lib/ibex/verifiable_generation_bundle.rb +86 -0
  234. data/lib/ibex/verification_report/builder.rb +159 -0
  235. data/lib/ibex/verification_report/canonical_ir.rb +123 -0
  236. data/lib/ibex/verification_report/logical_path.rb +68 -0
  237. data/lib/ibex/verification_report/validator.rb +329 -0
  238. data/lib/ibex/verification_report.rb +69 -0
  239. data/lib/ibex/verify/action_correspondence.rb +138 -0
  240. data/lib/ibex/verify/language_witness.rb +295 -0
  241. data/lib/ibex/verify/reference_collection.rb +190 -0
  242. data/lib/ibex/verify/result.rb +73 -0
  243. data/lib/ibex/verify/verifier.rb +598 -0
  244. data/lib/ibex/verify.rb +15 -0
  245. data/lib/ibex/version.rb +1 -1
  246. data/lib/ibex/watch/runner.rb +10 -1
  247. data/lib/ibex/watch/source_snapshot.rb +13 -8
  248. data/lib/ibex.rb +10 -0
  249. data/schema/{automaton-ir-v1.schema.json → automaton-ir-definitions.schema.json} +6 -6
  250. data/schema/{automaton-ir-v2.schema.json → automaton-ir.schema.json} +14 -7
  251. data/schema/bison-import-v1.schema.json +106 -0
  252. data/schema/conflict-explanation-review-v1.schema.json +196 -0
  253. data/schema/conflict-explanation-study-v1.schema.json +528 -0
  254. data/schema/construction-profile-v1.schema.json +779 -0
  255. data/schema/diff-v1.schema.json +41 -0
  256. data/schema/direct-ielr-decision-v1.schema.json +200 -0
  257. data/schema/equiv-v1.schema.json +64 -0
  258. data/schema/error-ux-review-v1.schema.json +609 -0
  259. data/schema/error-ux-round2-review-v1.schema.json +191 -0
  260. data/schema/error-ux-round2-v1.schema.json +519 -0
  261. data/schema/explain-v1.schema.json +63 -1
  262. data/schema/fix-v1.schema.json +64 -0
  263. data/schema/fix-v2.schema.json +66 -0
  264. data/schema/fix-v3.schema.json +101 -0
  265. data/schema/fuzz-regression-v1.schema.json +79 -0
  266. data/schema/fuzz-v1.schema.json +114 -0
  267. data/schema/{grammar-ir-v2.schema.json → grammar-ir-extensions.schema.json} +20 -65
  268. data/schema/{grammar-ir-v1.schema.json → grammar-ir-foundation.schema.json} +3 -3
  269. data/schema/grammar-ir.schema.json +271 -0
  270. data/schema/ielr-benchmark-v1.schema.json +85 -0
  271. data/schema/lexer-profile-v1.schema.json +491 -0
  272. data/schema/metrics-v1.schema.json +60 -0
  273. data/schema/reduce-v1.schema.json +22 -0
  274. data/schema/reduce-v2.schema.json +63 -0
  275. data/schema/table-artifact-v1.schema.json +377 -0
  276. data/schema/verification-report-v1.schema.json +222 -0
  277. data/schema/verify-v1.schema.json +42 -0
  278. data/sig/ibex/analysis/digraph.rbs +19 -0
  279. data/sig/ibex/bison_import/importer.rbs +140 -0
  280. data/sig/ibex/bison_import/tokenizer.rbs +91 -0
  281. data/sig/ibex/bison_import.rbs +95 -0
  282. data/sig/ibex/bounded_subprocess.rbs +76 -0
  283. data/sig/ibex/cli/ambiguity.rbs +6 -0
  284. data/sig/ibex/cli/analysis.rbs +43 -0
  285. data/sig/ibex/cli/bison_import.rbs +32 -0
  286. data/sig/ibex/cli/config.rbs +35 -0
  287. data/sig/ibex/cli/diagnostics.rbs +16 -3
  288. data/sig/ibex/cli/documentation.rbs +5 -1
  289. data/sig/ibex/cli/equiv.rbs +49 -0
  290. data/sig/ibex/cli/error_messages.rbs +6 -0
  291. data/sig/ibex/cli/explain.rbs +6 -0
  292. data/sig/ibex/cli/fix.rbs +53 -0
  293. data/sig/ibex/cli/formatting.rbs +5 -1
  294. data/sig/ibex/cli/fuzz.rbs +47 -0
  295. data/sig/ibex/cli/fuzz_regressions.rbs +40 -0
  296. data/sig/ibex/cli/generation_artifacts.rbs +21 -2
  297. data/sig/ibex/cli/generation_error_messages.rbs +2 -2
  298. data/sig/ibex/cli/grammar_tests.rbs +15 -3
  299. data/sig/ibex/cli/ir_tools.rbs +7 -19
  300. data/sig/ibex/cli/outputs.rbs +9 -3
  301. data/sig/ibex/cli/reduce.rbs +60 -0
  302. data/sig/ibex/cli/reduce_reporting.rbs +27 -0
  303. data/sig/ibex/cli/samples.rbs +8 -0
  304. data/sig/ibex/cli/verify.rbs +28 -0
  305. data/sig/ibex/cli/watch.rbs +2 -2
  306. data/sig/ibex/cli.rbs +79 -5
  307. data/sig/ibex/codegen/action_method_source.rbs +4 -4
  308. data/sig/ibex/codegen/explain.rbs +45 -25
  309. data/sig/ibex/codegen/generated_action_abi.rbs +14 -10
  310. data/sig/ibex/codegen/rbs.rbs +12 -10
  311. data/sig/ibex/codegen/report.rbs +12 -12
  312. data/sig/ibex/codegen/ruby.rbs +18 -15
  313. data/sig/ibex/codegen/ruby_actions.rbs +6 -6
  314. data/sig/ibex/codegen/ruby_syntax.rbs +10 -8
  315. data/sig/ibex/configuration/analysis_grammar.rbs +13 -0
  316. data/sig/ibex/configuration/explanation.rbs +195 -0
  317. data/sig/ibex/configuration/inspector.rbs +53 -0
  318. data/sig/ibex/configuration.rbs +242 -0
  319. data/sig/ibex/coverage/collector.rbs +16 -14
  320. data/sig/ibex/coverage/event_stream.rbs +12 -10
  321. data/sig/ibex/coverage/report.rbs +20 -18
  322. data/sig/ibex/coverage/runtime_event_validator.rbs +38 -36
  323. data/sig/ibex/delta_reducer.rbs +38 -0
  324. data/sig/ibex/diff.rbs +47 -0
  325. data/sig/ibex/equiv/machine.rbs +54 -0
  326. data/sig/ibex/equiv.rbs +129 -0
  327. data/sig/ibex/fix.rbs +138 -0
  328. data/sig/ibex/frontend/ast.rbs +33 -7
  329. data/sig/ibex/frontend/bootstrap_parser.rbs +2 -0
  330. data/sig/ibex/frontend/diagnostic.rbs +2 -2
  331. data/sig/ibex/frontend/formatter.rbs +38 -30
  332. data/sig/ibex/frontend/generated_parser.rbs +87 -77
  333. data/sig/ibex/frontend/generated_parser_base.rbs +4 -2
  334. data/sig/ibex/frontend/parser/declarations.rbs +3 -0
  335. data/sig/ibex/frontend/parser_configuration_support.rbs +27 -0
  336. data/sig/ibex/frontend/resolution.rbs +3 -2
  337. data/sig/ibex/frontend/source_cursor.rbs +2 -2
  338. data/sig/ibex/frontend/source_span.rbs +5 -2
  339. data/sig/ibex/frontend/token_adapter/declaration_state.rbs +13 -1
  340. data/sig/ibex/frontend/token_adapter.rbs +6 -0
  341. data/sig/ibex/fuzz.rbs +71 -0
  342. data/sig/ibex/generation_input.rbs +2 -2
  343. data/sig/ibex/generation_manifest.rbs +35 -32
  344. data/sig/ibex/generation_transaction_recovery.rbs +2 -2
  345. data/sig/ibex/generation_transaction_validation.rbs +2 -2
  346. data/sig/ibex/grammar_tests.rbs +2 -2
  347. data/sig/ibex/ir/automaton_ir.rbs +30 -11
  348. data/sig/ibex/ir/grammar_ir.rbs +41 -27
  349. data/sig/ibex/ir/lexer_ir.rbs +8 -8
  350. data/sig/ibex/ir/parser_contract.rbs +69 -0
  351. data/sig/ibex/ir/serialize.rbs +63 -28
  352. data/sig/ibex/ir/validator/automaton.rbs +47 -44
  353. data/sig/ibex/ir/validator/base.rbs +35 -31
  354. data/sig/ibex/ir/validator/grammar.rbs +78 -67
  355. data/sig/ibex/ir/validator/lexer.rbs +4 -4
  356. data/sig/ibex/ir.rbs +9 -3
  357. data/sig/ibex/lalr/build_metrics.rbs +42 -2
  358. data/sig/ibex/lalr/builder.rbs +75 -24
  359. data/sig/ibex/lalr/conflict_search.rbs +5 -2
  360. data/sig/ibex/lalr/counterexample.rbs +17 -14
  361. data/sig/ibex/lalr/direct_lookaheads.rbs +35 -28
  362. data/sig/ibex/lalr/goto_follows.rbs +89 -0
  363. data/sig/ibex/lalr/ielr/annotator.rbs +67 -0
  364. data/sig/ibex/lalr/ielr/bits.rbs +14 -0
  365. data/sig/ibex/lalr/ielr/inadequacy.rbs +24 -0
  366. data/sig/ibex/lalr/ielr/item_lookaheads.rbs +35 -0
  367. data/sig/ibex/lalr/ielr/pipeline.rbs +17 -0
  368. data/sig/ibex/lalr/ielr/split_stability.rbs +27 -0
  369. data/sig/ibex/lalr/ielr/split_state.rbs +14 -0
  370. data/sig/ibex/lalr/ielr/state_splitter.rbs +76 -0
  371. data/sig/ibex/lalr/ielr_partition.rbs +17 -5
  372. data/sig/ibex/lalr/inadequacy_report.rbs +21 -0
  373. data/sig/ibex/lalr/lookahead_propagation.rbs +38 -0
  374. data/sig/ibex/lalr/lr0_collection.rbs +50 -0
  375. data/sig/ibex/lalr/unreachable_states.rbs +25 -0
  376. data/sig/ibex/lalr.rbs +11 -1
  377. data/sig/ibex/location.rbs +6 -6
  378. data/sig/ibex/lsp/document_handlers.rbs +8 -8
  379. data/sig/ibex/lsp/initialization_handlers.rbs +12 -12
  380. data/sig/ibex/lsp/navigation_handlers.rbs +15 -12
  381. data/sig/ibex/lsp/parser_configuration_assistance.rbs +49 -0
  382. data/sig/ibex/lsp/position_codec.rbs +8 -4
  383. data/sig/ibex/lsp/request_handlers.rbs +4 -4
  384. data/sig/ibex/lsp/request_support.rbs +8 -8
  385. data/sig/ibex/lsp/server.rbs +16 -16
  386. data/sig/ibex/lsp/symbol_index.rbs +20 -21
  387. data/sig/ibex/lsp/symbol_index_builder.rbs +9 -8
  388. data/sig/ibex/lsp/symbol_occurrence.rbs +11 -5
  389. data/sig/ibex/lsp/transport.rbs +18 -6
  390. data/sig/ibex/lsp/workspace.rbs +3 -2
  391. data/sig/ibex/lsp/workspace_analyzer.rbs +1 -1
  392. data/sig/ibex/messages.rbs +26 -0
  393. data/sig/ibex/metrics.rbs +50 -0
  394. data/sig/ibex/normalize/diagnostics.rbs +4 -4
  395. data/sig/ibex/normalize/expander.rbs +2 -2
  396. data/sig/ibex/normalize/expression.rbs +10 -8
  397. data/sig/ibex/normalize/grammar_builder.rbs +11 -0
  398. data/sig/ibex/normalize/inline_expansion.rbs +59 -50
  399. data/sig/ibex/normalize/lexer.rbs +4 -4
  400. data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +15 -14
  401. data/sig/ibex/normalize/parameter_lowering.rbs +18 -18
  402. data/sig/ibex/normalize/parameters.rbs +13 -8
  403. data/sig/ibex/normalize/parser_configuration.rbs +23 -0
  404. data/sig/ibex/normalize.rbs +11 -5
  405. data/sig/ibex/racc_migration/report.rbs +8 -6
  406. data/sig/ibex/rake_task.rbs +1 -1
  407. data/sig/ibex/samples.rbs +13 -4
  408. data/sig/ibex/table_artifact/builder.rbs +93 -0
  409. data/sig/ibex/table_artifact/cst_projection.rbs +20 -0
  410. data/sig/ibex/table_artifact/document.rbs +27 -0
  411. data/sig/ibex/table_artifact/executor.rbs +66 -0
  412. data/sig/ibex/table_artifact/serializer.rbs +25 -0
  413. data/sig/ibex/table_artifact/validator/metadata.rbs +52 -0
  414. data/sig/ibex/table_artifact/validator/support.rbs +46 -0
  415. data/sig/ibex/table_artifact/validator/tables.rbs +63 -0
  416. data/sig/ibex/table_artifact/validator.rbs +66 -0
  417. data/sig/ibex/table_artifact.rbs +32 -0
  418. data/sig/ibex/table_simulation/result.rbs +8 -4
  419. data/sig/ibex/table_simulation/step.rbs +4 -2
  420. data/sig/ibex/tables.rbs +10 -9
  421. data/sig/ibex/verifiable_generation_bundle.rbs +24 -0
  422. data/sig/ibex/verification_report/builder.rbs +53 -0
  423. data/sig/ibex/verification_report/canonical_ir.rbs +41 -0
  424. data/sig/ibex/verification_report/logical_path.rbs +34 -0
  425. data/sig/ibex/verification_report/validator.rbs +114 -0
  426. data/sig/ibex/verification_report.rbs +44 -0
  427. data/sig/ibex/verify/action_correspondence.rbs +50 -0
  428. data/sig/ibex/verify/language_witness.rbs +112 -0
  429. data/sig/ibex/verify/reference_collection.rbs +63 -0
  430. data/sig/ibex/verify/result.rbs +52 -0
  431. data/sig/ibex/verify/verifier.rbs +170 -0
  432. data/sig/ibex/verify.rbs +6 -0
  433. data/sig/ibex/watch/runner.rbs +12 -2
  434. data/sig/ibex/watch/source_snapshot.rbs +13 -9
  435. metadata +232 -12
  436. data/lib/ibex/ir/migration.rb +0 -120
  437. data/sig/ibex/ir/migration.rbs +0 -34
@@ -1,21 +1,45 @@
1
+ ---
2
+ title: Release readiness
3
+ description: Outcome-based release evidence, limitations, and the current publication decision.
4
+ ---
5
+
1
6
  # v1.0 readiness report
2
7
 
3
8
  This is the outcome-based v1.0 decision required by the project design. It
4
- records measurements taken on 2026-07-27 with Ruby 4.0.0 on
5
- `arm64-darwin24`. Passing the implementation checklist is not sufficient for a
6
- stable release.
9
+ records evidence current through 2026-08-08. Performance measurements used
10
+ Ruby 4.0.0 on `arm64-darwin24`. Passing the implementation checklist is not
11
+ sufficient for a stable release.
7
12
 
8
13
  ## Decision
9
14
 
10
15
  **HOLD v1.0.** Compatibility behavior, scale construction, semantic-value
11
- signatures, and the repository compatibility suite have evidence. The external
12
- generator/runtime performance target is not met, and the published ten-case
13
- error comparison has not received independent third-party review.
16
+ signatures, and the repository compatibility suite have evidence. The exact
17
+ formal public performance rerun is now recorded for the measured revision
18
+ below. The published ten-case error comparison has not received independent
19
+ third-party review. Its machine-readable
20
+ [`R001` status](error-ux-review-status-v1.json) is
21
+ `HOLD / awaiting_independent_review`; the linked status leads to the complete
22
+ rubric, closed record schema, immutable evidence identity, and imported-record
23
+ registry.
24
+
25
+ <!-- r001-review-status:start -->
26
+ R001: `HOLD` — [`awaiting_independent_review`](error-ux-review-status-v1.json).
27
+ <!-- r001-review-status:end -->
28
+
29
+ Feature development is not frozen. The open release gate blocks publication of
30
+ v1.0, not feature development. New work remains subject to the feature budgets,
31
+ maturity rules, compatibility checks, and exact-revision release gates
32
+ documented by the project. The current Grammar IR and Automaton IR contracts
33
+ remain closed and validated; before v1.0, incompatible changes are coordinated
34
+ with their writers, readers, schemas, fixtures, and downstream consumers.
14
35
 
15
- The feature freeze remains in force while those two release gates are open.
16
36
  The format-v6 batch Red/Green CST has been selected as part of the initial
17
- Stable v1 API. Its syntax-only incremental layer remains Experimental. Other Preview and
18
- Experimental features may continue to ship in prereleases without promotion.
37
+ Stable v1 API. Its syntax-only incremental layer remains Experimental. Other
38
+ Preview and Experimental features may continue to ship in prereleases without
39
+ promotion; before v1.0, those surfaces can change between prereleases when the
40
+ release notes, migration note, regressions, and maturity evidence are updated.
41
+ The release lock applies to Stable declarations and versioned persisted
42
+ contracts, not to every Preview implementation detail or evidence capture.
19
43
 
20
44
  ## KPI result
21
45
 
@@ -24,9 +48,10 @@ Experimental features may continue to ship in prereleases without promotion.
24
48
  | Three public-gem migrations | Pass with documented adapters | Namae, BCDice, and Nokogiri behavior suites below |
25
49
  | Hundreds-of-productions scale | Pass | 501 productions, 503 states, 125.008 ms average complete build |
26
50
  | Ten-case error UX comparison | Partial | 10/10 snapshots and 8/10 useful repairs are public; independent review is missing |
27
- | Generator and parser performance at least racc | Fail | Reuse medians are at parity, but only Nokogiri's interval passes; all cold-generation and new-instance rows fail |
28
- | Semantic-value RBS and typed ratchet | Pass | Generated reduction signatures include declared RHS/LHS types; whole-library Steep is 89.6% typed |
51
+ | Public generator/runtime performance baseline | Pass at measured revision | Direct formal ten-run result artifact is published below; the historical projection remains retained separately |
52
+ | Semantic-value RBS and typed ratchet | Pass | Generated reduction signatures include declared RHS/LHS types; the 2026-08-08 evidence revision measured whole-library Steep at 88.4% typed |
29
53
  | Compatibility suite unbeaten | Pass at the measured revision | Current black-box, self-host, IR, property, and runtime suites are green |
54
+ | Release basis | Pass without publication | Stable declaration diff is 0 across 48 locked files; both gems build byte-identically under two environments |
30
55
 
31
56
  ## Public-gem migration evidence
32
57
 
@@ -60,65 +85,72 @@ that omits `super` plus historical value-stack reads, and an unqualified
60
85
 
61
86
  ## Formal Pure Ruby performance comparison
62
87
 
63
- The formal artifact was collected from clean revision `3fda78c` with ten
88
+ <!-- comparative-evidence:racc-public-performance-2026-07-31:start -->
89
+ At clean Ibex revision 984d4ae7a1c96db4c71e3077669842b7bbc3b4ea, the readiness
90
+ projection for three pinned workloads on Ruby 4.0.0, arm64-darwin24, with YJIT disabled
91
+ records slower cold generation and new-instance runtime than Racc 1.8.1's Ruby backend;
92
+ the direct formal result artifact is absent, so this is evidence-pending and non-publishable
93
+ as a comparative claim.
94
+
95
+ Evidence record ID: `racc-public-performance-2026-07-31`. Its complete scope,
96
+ evidence paths, missing artifact, and limitations are registered in
97
+ [`claims.yml`](claims.yml) under the [comparison policy](comparison-policy.md).
98
+ CPU model, kernel release, and processor count were not retained in this
99
+ readiness projection. Host CPU and host OS were also not recorded as separate
100
+ fields. The measurements below do not describe the current checkout.
101
+
102
+ The historical readiness projection says the measurement was collected on
103
+ 2026-07-31 from clean revision
104
+ `984d4ae7a1c96db4c71e3077669842b7bbc3b4ea` with ten
64
105
  alternating isolated runs per implementation, 50 warm-up workloads, 250
65
106
  measured workloads, and 10,000 bootstrap samples. Each workload parses the
66
107
  five fixed public inputs. Ruby 4.0.0 ran with YJIT disabled; Racc 1.8.1 was
67
108
  forced to its Ruby backend and every worker verified the selected runtime.
68
- Ratios below are Ibex divided by Racc. Bold values meet the gate, whose timing
69
- and allocation metrics require the bootstrap interval's upper bound to be no
70
- greater than 1.0.
109
+ Ratios below are Ibex divided by Racc; time cells include the bootstrap 95%
110
+ interval. The harness's `target_met` field marks absolute parity when the
111
+ interval's upper bound is no greater than 1.0. That field is diagnostic:
112
+ v1.0 requires publication of measurements and their conditions, while a
113
+ future performance gate may reject only a relative regression measured under
114
+ an identical environment and configuration.
71
115
 
72
116
  | Project | Cold generation time | Reuse time | Reuse allocations | New-instance time | New-instance allocations | Generated bytes |
73
117
  |---|---:|---:|---:|---:|---:|---:|
74
- | Namae | 1.194x | 0.994x | **0.849x** | 1.185x | 1.208x | **0.862x** |
75
- | BCDice command | 1.204x | 0.995x | **0.666x** | 1.258x | 1.129x | **0.981x** |
76
- | Nokogiri CSS | 1.187x | **0.953x** | **0.662x** | 1.167x | 1.075x | **0.937x** |
118
+ | Namae | 1.238x [1.184, 1.272] | 0.985x [0.966, 1.032] | 0.849x | 1.194x [1.157, 1.248] | 1.190x | 0.862x |
119
+ | BCDice command | 1.329x [1.278, 1.420] | 1.052x [1.008, 1.075] | 0.666x | 1.373x [1.326, 1.415] | 1.103x | 0.981x |
120
+ | Nokogiri CSS | 1.309x [1.277, 1.343] | 0.985x [0.963, 1.029] | 0.662x | 1.186x [1.149, 1.255] | 1.051x | 0.937x |
77
121
 
78
122
  Result values and ordered result sequences are equivalent in every runtime
79
123
  row. The measured parser-time medians in milliseconds per parse were
80
- 0.038783/0.039015 (Ibex/Racc) for Namae reuse,
81
- 0.019542/0.019646 for BCDice reuse, and
82
- 0.024074/0.025269 for Nokogiri reuse. The corresponding new-instance medians
83
- were 0.047493/0.040076, 0.025937/0.020618, and 0.031041/0.026609.
84
-
85
- The remaining runtime gap is isolated to parser-instance construction and the
86
- per-instance mutation tracker; the reused hot loop's point estimates are at
87
- practical parity, although Namae and BCDice still need narrower passing
88
- intervals. Cold generation remains 18.7–20.4% slower and is dominated by
89
- process/load, frontend, and code-generation setup. These are evidence for the
90
- release decision, not portable scores.
91
-
92
- ## Superseded native-backend diagnostic
93
-
94
- The previous artifact was collected from clean revision `53aa4ab` with ten
95
- alternating isolated runs per implementation, 50 warm-up workloads, 250
96
- measured workloads, and 10,000 bootstrap samples. Each workload parses the
97
- five fixed public inputs. Ruby 4.0.0 ran with YJIT disabled; racc 1.8.1 was
98
- verified to use its native backend. The formal release contract now compares
99
- the two Pure Ruby runtimes, so these stricter native-backend measurements are
100
- retained only as diagnostic context and do not decide the KPI. Ratios below
101
- are Ibex divided by racc.
102
-
103
- | Project | Cold generation time | Reuse time | Reuse allocations | New-instance time | New-instance allocations | Generated bytes |
124
+ 0.039443/0.040048 (Ibex/Racc) for Namae reuse,
125
+ 0.020925/0.019897 for BCDice reuse, and
126
+ 0.024892/0.025280 for Nokogiri reuse. The corresponding new-instance medians
127
+ were 0.048234/0.040413, 0.027523/0.020044, and 0.030420/0.025642.
128
+
129
+ The results deliberately retain the unfavorable rows: cold generation is
130
+ 23.8–32.9% slower, and new-instance parsing is 18.6–37.3% slower. Reuse point
131
+ estimates range from 1.5% faster to 5.2% slower. Ibex allocates fewer objects
132
+ for every reuse workload, while new-instance allocation ratios remain
133
+ 1.051–1.190x. Generated output is smaller for all three grammars. These values
134
+ are a release baseline, not portable scores or an assertion of parity.
135
+ <!-- comparative-evidence:racc-public-performance-2026-07-31:end -->
136
+
137
+ ## Exact-revision formal rerun
138
+
139
+ <!-- comparative-claim:racc-public-performance-2026-08-08:start -->
140
+ At clean Ibex revision 26e94ce631bf5c075ecbca0205a34a8c231c31d9, on Ruby 4.0.0,
141
+ arm64-darwin24, with YJIT disabled, the direct formal comparison of the pinned
142
+ Namae, BCDice command, and Nokogiri CSS workloads against Racc 1.8.1 produced
143
+ equivalent result sequences; Ibex recorded slower cold generation and new-instance
144
+ parsing, fewer reuse allocations, and smaller generated output in every workload.
145
+
146
+ | Project | Cold generation ratio | Reuse time ratio | Reuse allocations ratio | New-instance time ratio | New-instance allocations ratio | Generated bytes ratio |
104
147
  |---|---:|---:|---:|---:|---:|---:|
105
- | Namae | 1.210x | 1.177x | **0.970x** | 1.408x | 1.376x | **0.862x** |
106
- | BCDice command | 1.211x | 1.943x | **0.852x** | 2.445x | 1.430x | **0.981x** |
107
- | Nokogiri CSS | 1.236x | 1.562x | **0.881x** | 1.993x | 1.418x | **0.937x** |
148
+ | Namae | 1.317830 | 0.996320 | 0.854462 | 1.209687 | 1.207559 | 0.861519 |
149
+ | BCDice command | 1.309690 | 1.010467 | 0.675012 | 1.331780 | 1.129299 | 0.981449 |
150
+ | Nokogiri CSS | 1.288118 | 0.994802 | 0.670484 | 1.193522 | 1.074838 | 0.936806 |
108
151
 
109
- Result values and ordered result sequences are equivalent in every runtime
110
- row. The measured parser-time medians in milliseconds per parse were
111
- 0.038938/0.033094 (Ibex/racc) for Namae reuse,
112
- 0.020118/0.010354 for BCDice reuse, and
113
- 0.024413/0.015626 for Nokogiri reuse. The corresponding new-instance medians
114
- were 0.046953/0.033340, 0.026933/0.011016, and 0.030744/0.015426.
115
-
116
- Profiles attribute the remaining reuse gap to the Pure Ruby direct LR loop
117
- after lexer and semantic-action costs. New-instance rows additionally include
118
- the per-instance tracker that preserves runtime hook mutation semantics.
119
- Cold-generation profiles are dominated by process/load cost plus frontend and
120
- code-generation work. These are diagnostic optimization evidence, not
121
- portable scores or formal release evidence.
152
+ The complete formal result is [`2026-08-08-8c9cef999d09-ruby-4.0.0-arm64-darwin24.json`](../benchmark/results/public/2026-08-08-8c9cef999d09-ruby-4.0.0-arm64-darwin24.json). It records ten alternating isolated runs per implementation and scenario, 50 warm-up workloads, 250 measured workloads, five behavior probes, 10,000 bootstrap samples, exact public checkout revisions, and equivalent result and result-sequence digests.
153
+ <!-- comparative-claim:racc-public-performance-2026-08-08:end -->
122
154
 
123
155
  ## Scale evidence
124
156
 
@@ -145,19 +177,45 @@ presented as a substitute for an application-specific benchmark.
145
177
  malformed JSON inputs against the public racc callback. Eight selected repairs
146
178
  were assessed useful. A maintainer assessment is not independent review; at
147
179
  least one external reviewer must record a review of the cases and usefulness
148
- labels before this KPI passes.
149
-
150
- The current whole-library `steep stats` result is 18,115 typed calls and 2,097
151
- untyped calls out of 20,212, or 89.6% typed. Generated parser RBS refines
180
+ labels before this KPI passes. Reviewers use the versioned
181
+ [`independent rubric`](error-ux-review-rubric-v1.md), generate a draft with the
182
+ exact checkout and environment identity, set all structured consent fields, and
183
+ publish the final permalink-free payload at a full-SHA blob URL. Maintainers
184
+ import the exact bytes and register publication provenance separately, without
185
+ rewriting. Ordinary CI validates the offline kit; the release gate performs
186
+ fail-closed blob checks and requires the source owner, GitHub API author,
187
+ publisher, and reviewer logins to agree. This establishes only GitHub namespace
188
+ control and account metadata, not cryptographic identity or a signature. The
189
+ gate remains intentionally failing while the public status is HOLD.
190
+
191
+ The 2026-07-31 evidence snapshot recorded 23,517 typed calls and 2,946
192
+ untyped calls out of 26,463, or 88.9% typed. Generated parser RBS refines
152
193
  declared terminal, nonterminal, RHS tuple, and reduction result types. Untyped
153
194
  values remain explicit at undeclared grammar symbols, decoded JSON, dynamic
154
- table cells, and opaque application Ruby boundaries.
195
+ table cells, and opaque application Ruby boundaries. The current repository
196
+ result is maintained in the generated type-statistics block in `README.md`.
197
+
198
+ ## Release-basis evidence
199
+
200
+ `bundle exec rake release:reproducible` compares 47 normalized Stable RBS
201
+ declaration files with the v0.2.0 baseline. The current result has zero
202
+ differences; the installed-Gem embedded-source helper is an internal packaging
203
+ implementation and is outside that public lock. The task also builds both
204
+ gems twice under distinct locale, timezone, and frozen-string settings and
205
+ requires byte-identical artifacts. SHA-256 digests are emitted for the exact
206
+ candidate revision rather than recorded as if the current HOLD revision were
207
+ a release.
208
+
209
+ No release signing credential is stored in this repository. A signature or
210
+ provenance attestation must be supplied by a protected external release
211
+ environment after the outcome gates pass; an unsigned local test key would not
212
+ establish publisher identity.
155
213
 
156
214
  ## Actions required to release v1.0
157
215
 
158
- 1. Optimize cold generation and parser-instance construction, then repeat the
159
- formal Pure Ruby measurements until no row is slower than Racc.
160
- 2. Obtain and link an independent review of the ten error cases and usefulness
161
- judgments; revise the versioned assessment if the review disagrees.
162
- 3. Re-run every compatibility, IR, type, benchmark, and site gate on the exact
216
+ 1. Obtain and publish an independent review of the ten error cases using the
217
+ R001 rubric, then import the record byte-for-byte with its immutable
218
+ permalink and consent. Preserve disagreements separately from the normative
219
+ maintainer assessment.
220
+ 2. Re-run every compatibility, IR, type, benchmark, and site gate on the exact
163
221
  release revision.
@@ -0,0 +1,123 @@
1
+ # Existing bounded repair semantics
2
+
3
+ Ibex bounded repair is an opt-in Experimental runtime facility. Assign an
4
+ immutable `Ibex::Runtime::RepairPolicy` before starting a parser session. With
5
+ no policy, parsing does not search or prefetch for repairs and existing error
6
+ recovery is unchanged.
7
+
8
+ ## Search state and bounds
9
+
10
+ `RepairSearch` runs Dijkstra search over configurations containing:
11
+
12
+ - a copied LR state stack;
13
+ - the buffered-input index;
14
+ - consecutive successful shifts;
15
+ - accumulated edit cost and ordered edits;
16
+ - whether that configuration has reached the proof goal.
17
+
18
+ Insertion, deletion, and replacement are the only edits. The default costs are
19
+ 1, 1, and 2, with maximum cost 3. Search also has independent defaults of 5,000
20
+ simulated configurations, 8 lookahead tokens, 3 proof shifts, and stack depth
21
+ 256. Every policy number is positive and proof shifts cannot exceed lookahead.
22
+
23
+ The queue orders configurations lexicographically by:
24
+
25
+ 1. total cost;
26
+ 2. semantic-value risk;
27
+ 3. ordered edit keys `(input position, delete|insert|replace rank, token id)`;
28
+ 4. goal before non-goal;
29
+ 5. more successful shifts;
30
+ 6. earlier buffered-input index;
31
+ 7. LR state stack.
32
+
33
+ Word-like token names add semantic-value risk; punctuation does not. This is a
34
+ deterministic tie-break, not a claim that punctuation edits are correct.
35
+ Candidate inserted/replacement token IDs are ordered and exclude EOF and the
36
+ reserved `error` token. A plan succeeds after the configured consecutive
37
+ shifts or accept.
38
+
39
+ Search simulates table actions and reductions on integer state stacks only. It
40
+ does not call semantic actions, `on_error`, `on_repair`, lexer actions, or
41
+ runtime observers. Reduction-stack cycles, excess stack depth, excess cost,
42
+ and excess configuration count stop a path. Pull parsing may read ahead to the
43
+ lookahead bound. An incomplete push prefix yields the internal `NEED_INPUT`
44
+ sentinel and waits for more input.
45
+
46
+ The compatibility `RepairSearch#search` projection still returns the legacy
47
+ `RepairPlan | NEED_INPUT | nil` shape. The additive `search_result` method
48
+ retains a frozen typed outcome (`:selected`, `:need_input`, `:exhausted`, or
49
+ `:not_found`) for syntax tooling, so bounded exhaustion is not confused with a
50
+ complete search that found no plan.
51
+
52
+ ## Selection, hooks, and replay
53
+
54
+ On a reported syntax error, the runtime captures the error context and CST
55
+ error, publishes the runtime `error` event, and calls `on_error`. If search
56
+ selected a plan, `on_repair(plan)` is called next. If either hook raises, its
57
+ exception propagates before edited tokens are applied.
58
+
59
+ After both hooks return, the runtime rebuilds the buffered token prefix:
60
+
61
+ | Edit | Replay token value | Replay location | CST effect |
62
+ | --- | --- | --- | --- |
63
+ | insert | `nil` | location at the insertion point | missing token |
64
+ | delete | absent from replay | original source retained separately | skipped/error trivia |
65
+ | replace | original token value | original token location | error-marked replacement |
66
+
67
+ The rebuilt prefix then passes through ordinary shift/reduce/accept handling.
68
+ Committed semantic actions and observers therefore run normally; speculative
69
+ search never runs them. Replay emits normal parser events and does not invent a
70
+ `recover` event for the selected repair. The original syntax error remains a
71
+ diagnostic even if replay accepts.
72
+
73
+ Inserted `nil` and a replacement's retained value are compatibility mechanics,
74
+ not evidence of user intent. A syntactically accepted repair can still be
75
+ semantically unsafe.
76
+
77
+ ## Syntax-only editor proposals
78
+
79
+ `SyntaxSession#repair` is a separate Experimental boundary for callers that
80
+ need byte edits rather than semantic replay. It runs the same bounded search
81
+ on a fresh private parser, captures absolute source ranges, resolves source
82
+ spelling only from caller-provided text or conservative punctuation literals,
83
+ and validates the applied bytes with a fresh syntax session. Production actions
84
+ and the application's `on_repair` callback do not run, and the result has no
85
+ semantic `value`. The originating session remains unchanged.
86
+
87
+ `SyntaxRepairResult` distinguishes `:accepted`, `:progress`, and `:rejected`
88
+ from bounded `:exhausted` and `:not_found` outcomes and selected-but-unavailable
89
+ cases such as missing token spelling or multiple repair segments. Accepted
90
+ results require a diagnostic-free fresh parse consuming all edited bytes. For
91
+ error results, `updated_source` keeps the exact bytes while the CST may expose
92
+ only the consumed prefix under the existing error CST contract. See [E002
93
+ syntax-only repair](investigations/E002-syntax-only-repair-result.md) and
94
+ [ADR 0023](decisions/0023-syntax-only-repair-results.md).
95
+
96
+ ## CST and source ownership
97
+
98
+ CST parsing retains the original source bytes. Insertions are represented by
99
+ missing nodes, replacements carry an error flag, and deleted token bytes are
100
+ preserved as skipped-token trivia rather than silently disappearing. These
101
+ representations are part of the existing CST error-path contract, not a text
102
+ edit API. `RepairPlan#position` is a buffered token index, not a source-byte
103
+ offset.
104
+
105
+ ## Executable coverage
106
+
107
+ <!-- repair-semantics:coverage:start -->
108
+ | Concept | Executable evidence |
109
+ | --- | --- |
110
+ | policy-and-default-off | `test/runtime/repair_test.rb` |
111
+ | dijkstra-priority-and-outcomes | `test/runtime/repair_characterization_test.rb` |
112
+ | typed-search-outcomes | `test/runtime/repair_characterization_test.rb` |
113
+ | values-locations-and-replay | `test/runtime/repair_test.rb` |
114
+ | hooks-actions-and-observers | `test/runtime/repair_test.rb` |
115
+ | pull-and-push-bounds | `test/runtime/repair_test.rb` |
116
+ | cst-representation | `test/codegen/cst_test.rb` |
117
+ | cst-source-fidelity | `test/runtime/cst_fidelity_property_test.rb` |
118
+ | syntax-only-repair-projection | `test/runtime/syntax_repair_test.rb` |
119
+ <!-- repair-semantics:coverage:end -->
120
+
121
+ The H003 [round-two evidence](error-ux-round2.md) records exact selected plans
122
+ and fresh reparses but keeps external usefulness judgments on HOLD. Neither
123
+ that evidence nor this characterization promotes bounded repair to Stable.