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
@@ -0,0 +1,199 @@
1
+ # Verifier trust boundary
2
+
3
+ `ibex verify` checks a validated Automaton IR document against expectations
4
+ derived from the Grammar IR embedded in that document. It is a semantic
5
+ cross-check for the current Automaton IR. It is not a proof checker for a
6
+ generated parser, a verifier for arbitrary Ruby, or a security sandbox.
7
+
8
+ ## Input and result boundary
9
+
10
+ The command reads one complete JSON document with `File.binread`.
11
+ `IR::Validator` first parses it and validates its raw shape, schema version,
12
+ symbol/state/production references, and conflict records and summaries. It
13
+ then calls `IR::Serialize.load` to construct immutable Grammar and Automaton
14
+ IR objects. Finally, before returning the Automaton, it recomputes and checks
15
+ the embedded-grammar digest. Those validation and construction steps are a
16
+ prerequisite to, not a substitute for, the semantic checks below.
17
+
18
+ The embedded Grammar IR is the verifier's semantic source of truth. Supplying
19
+ `--grammar=GRAMMAR.json` requires byte-deterministic serialized equality with
20
+ that embedded Grammar IR, but does not bind either IR to an original `.y`
21
+ file. Recomputing `grammar_digest` detects accidental inconsistency inside the
22
+ document; an author who changes both the embedded grammar and its digest has
23
+ created a different self-consistent input, not a verifier failure.
24
+
25
+ A semantic violation produces an invalid result and CLI exit status 1. A
26
+ completed run with no named violation produces a valid result and exit status
27
+ 0 within this document's boundary. Reference-construction exhaustion is a
28
+ separate result with exit status 2; it is neither validity nor a violation.
29
+
30
+ ## Named invariants
31
+
32
+ The report's invariant IDs are stable schema values. “Default” means every
33
+ run; “strict” means the ID is listed only for `--strict`.
34
+
35
+ <!-- verifier-checks:start -->
36
+ | ID | Mode | What the implementation checks |
37
+ | --- | --- | --- |
38
+ | V1 | default | The embedded grammar digest, state item soundness against the algorithm-specific reference, transition shift preservation, nonterminal transition/GOTO agreement, and exact single-candidate ACTION selection. Unsupported programmatic algorithm values are also V1. |
39
+ | V2 | strict | Collection completeness: exact LR(0) core coverage for SLR; exact derived-state/item coverage for LALR(1) and LR(1); and canonical-core lookahead-union coverage for IELR(1). |
40
+ | V3 | default | Every completed SLR item has exactly its independently requested FOLLOW lookaheads (or EOF for an augmented production). Non-completed SLR lookaheads cannot select ACTION cells and are deliberately outside this check. |
41
+ | V4 | default | Default actions are reductions, terminals with no candidate remain errors after expanding defaults and explicit masks, and rebuilt plain/compact ACTION, GOTO, and default rows are equal. A table transformation failure is also V4 in default mode. |
42
+ | V5 | strict | The same rebuilt plain/compact row equality that default mode reports as V4 is classified as V5 in strict mode. Strict mode does not consume a separately supplied table artifact. |
43
+ | V6 | default | Every submitted state is reachable from an entry through submitted transitions, GOTOs, or shift actions, and every embedded-grammar nonterminal derives some terminal sentence. |
44
+ | V7 | default | For each terminal, effective zero-length reductions and their submitted GOTOs do not form a state cycle that can reduce forever without consuming that terminal. |
45
+ | V8 | default | A cell with multiple derived candidates has a declared resolver; resolver records are unique and complete for their token, name only cell candidates, and choose the effective ACTION (or an allowed error). |
46
+ | V9 | strict | For IELR, a bounded canonical-reference witness compares accepted/error outcomes for terminal sequences up to three tokens and fails closed on witness-budget exhaustion. It is a semantic regression witness, not unbounded language equivalence or split-proof verification. Non-IELR algorithms do not execute the witness. |
47
+ <!-- verifier-checks:end -->
48
+
49
+ Default and strict both construct the algorithm-specific reference and both
50
+ rebuild and compare plain and compact rows. Strict adds the V2 completeness
51
+ requirements. It also changes a row mismatch's identifier from V4 to V5; it
52
+ does not add another table representation or inspect generated table bytes.
53
+ In particular, default-mode item checks are soundness/subset checks and can
54
+ accept an incomplete collection that strict mode rejects. For `ielr1`, strict
55
+ mode additionally runs V9. V9 compares the submitted table with a
56
+ verifier-owned canonical LR(1) machine over a finite breadth-first token set;
57
+ a clean result is evidence only within the recorded token and case bounds.
58
+
59
+ ## Supported algorithms and reference cost
60
+
61
+ The CLI validator accepts only the following serialized algorithm identities.
62
+
63
+ <!-- verifier-algorithms:start -->
64
+ | Automaton IR value | Reference and comparison |
65
+ | --- | --- |
66
+ | `slr` | Build the full LR(0) collection. Completed submitted items use FOLLOW sets for lookaheads. Strict mode requires exact LR(0) core coverage. |
67
+ | `lalr1` | Build the full canonical LR(1) collection and union states with the same LR(0) core. Submitted items are subsets by default; strict mode requires the complete merged states. |
68
+ | `ielr1` | Build the full canonical LR(1) collection and its LALR core unions. Each submitted partition must be a subset of its core union; strict mode requires the union of submitted partitions to cover it and runs the bounded V9 acceptance witness. This does not prove unbounded IELR adequacy, the reason for each split, or split witnesses. |
69
+ | `lr1` | Build the full canonical LR(1) collection. Submitted items are subsets by default; strict mode requires the complete canonical states. |
70
+ <!-- verifier-algorithms:end -->
71
+
72
+ Thus LALR(1), IELR(1), and LR(1) verification enumerate the canonical LR(1)
73
+ collection even in default mode. That collection can grow exponentially with
74
+ the grammar. SLR enumerates LR(0), but is still a whole-collection operation.
75
+ The current verifier is consequently a bounded reference oracle, not a
76
+ scale-independent certificate checker. A serialized unknown algorithm is
77
+ rejected structurally before the CLI verifier runs; an Automaton object made
78
+ directly with an unknown value receives V1.
79
+
80
+ The supported `ielr1` check is intentionally narrower than a future direct
81
+ IELR verifier: it checks membership, union coverage, and (in strict mode) a
82
+ bounded acceptance witness. It does not establish conflict preservation,
83
+ canonical state correspondence, or split witnesses. Raw ACTION-cell
84
+ correspondence remains a diagnostic: IELR state merging can produce a
85
+ canonical error cell versus a target reduction cell without an observed
86
+ acceptance difference in the bounded witness.
87
+
88
+ ## Limits and exhaustion
89
+
90
+ The two CLI limits must be positive and apply only to reference collection
91
+ construction.
92
+
93
+ <!-- verifier-limits:start -->
94
+ | Limit | Default | Meaning |
95
+ | --- | ---: | --- |
96
+ | `--max-states` | `100000` | Maximum distinct reference states inserted. |
97
+ | `--max-items` | `1000000` | Work-account limit for augmented seed items and new closure-expansion items. It is not the final collection's unique-item count and does not count every moved GOTO kernel item. |
98
+ <!-- verifier-limits:end -->
99
+
100
+ Exceeding either limit raises `Verify::BudgetExceeded`; the CLI emits
101
+ `result: "budget_exhausted"` with the bounds and exits 2. Strict mode uses the
102
+ same two limits and has no separate completeness budget.
103
+
104
+ These limits do **not** bound input bytes, JSON parsing, IR validation,
105
+ embedded grammar size, submitted state/table size, nullable/FIRST/FOLLOW
106
+ analysis, table compression, all verifier loops, wall-clock time, Ruby heap,
107
+ or process resources. An operating-system failure, timeout, or memory
108
+ exhaustion is not converted into a verifier budget result. Callers handling
109
+ hostile inputs need an outer byte/time/memory/process boundary.
110
+
111
+ ## Trusted computing base and independence
112
+
113
+ Here, “independent” means only that `Verify::ReferenceCollection` implements
114
+ its own LR(0)/LR(1) closure, GOTO, and collection traversal and does not require
115
+ or call `LALR::Builder`. It does not mean independently authored, third-party
116
+ reviewed, formally verified, cryptographically certified, or free of shared
117
+ implementation defects.
118
+
119
+ The result trusts all of the following:
120
+
121
+ | Trusted component or input | Why it is in the TCB |
122
+ | --- | --- |
123
+ | Embedded Grammar IR | It defines the grammar against which the submitted automaton is checked. |
124
+ | `IR::Validator`, `IR::Serialize`, IR migration and IR model classes | They validate, decode, canonicalize, hash, and expose the input. |
125
+ | `Verify::Verifier`, `Verify::ReferenceCollection`, and result classes | They derive and evaluate all named semantic invariants. |
126
+ | `Analysis::Sets` | It supplies nullable, FIRST, and FOLLOW data. The parser builder also uses this component, so defects here can be correlated. |
127
+ | `Tables.build`, `Tables::Compact`, and `Tables::CompactActions` | The verifier rebuilds both in-memory table views with production table code. Plain/compact comparison is therefore not an independent compact-table implementation. |
128
+ | Ruby runtime and standard library (`JSON`, `Set`, `Digest`, file I/O) | They parse, enumerate, compare, hash, and allocate the checked data. |
129
+ | Host resource isolation | The verifier itself supplies only the two reference-work limits above. |
130
+
131
+ Excluding `LALR::Builder` is useful deliberate duplication, but the shared
132
+ sets, IR, table transformation, language runtime, and embedded input remain in
133
+ the TCB. A valid report is evidence against the implemented fault model, not
134
+ an unqualified correctness proof.
135
+
136
+ ## Explicit non-goals
137
+
138
+ <!-- verifier-non-goals:start -->
139
+ | Boundary | What is not verified |
140
+ | --- | --- |
141
+ | `source-to-ir` | Correct parsing or normalization of the original grammar source, or provenance from that source to the embedded Grammar IR. |
142
+ | `generated-ruby` | Generated Ruby source, wrapper structure, digests, loading behavior, or binding between generated output and this Automaton IR. |
143
+ | `runtime` | The parser runtime implementation, actual parser execution, recovery behavior under application callbacks, or plain/compact behavior after code generation. |
144
+ | `semantic-actions` | Meaning, type safety, termination, side effects, or correctness of parser actions and user-code sections. Their text is opaque and is never evaluated. |
145
+ | `lexer-actions` | Lexer IR, tokenization, generated lexer actions, handwritten lexers, or parser-to-lexer feedback. |
146
+ | `resolver-policy` | Whether a resolver's claimed `by` reason correctly applies grammar precedence/associativity policy; V8 checks record/candidate/selected-cell consistency. |
147
+ | `grammar-properties` | Unambiguity, language equivalence to another grammar/parser, completeness of `%expect` as a design claim, or application semantics. |
148
+ | `ielr-adequacy` | Unbounded language equivalence, conflict preservation, why an IELR state was split, or a proof that every split has the required canonical correspondence. Strict V9 supplies only a bounded acceptance witness. |
149
+ | `data-only-artifact` | The standalone `ibex verify` command does not consume a supplied executable table artifact, compact-table bytes, generated bundle, manifest/report binding, or artifact digest. The current Automaton IR contains states and actions, and the verifier rebuilds table views from them. The separate bundle report records this verifier result and binds table identities without widening V1-V9. |
150
+ | `security` | Authenticity, trusted publication, signatures, sandboxing, confidentiality, or availability under hostile resource use. |
151
+ <!-- verifier-non-goals:end -->
152
+
153
+ Opaque action and user-code strings participate in serialized Grammar IR and
154
+ therefore its digest, but checking that self-contained digest is not semantic
155
+ verification of the code and never executes it.
156
+
157
+ The data-only table and scoped bundle are separate layers around this
158
+ verifier. Their validators check closed formats and digest relationships, but
159
+ they do not make the standalone V1-V9 implementation consume or independently
160
+ verify sidecar bytes. Consequently `ibex verify` must still not be described
161
+ as validating generated Ruby, table artifacts, or manifests.
162
+
163
+ ## Committed fault corpus
164
+
165
+ `test/verify/verifier_test.rb` mutates a generated document in twenty named
166
+ ways while keeping it acceptable to `IR::Validator`, then requires strict
167
+ verification to reject it. The table records the invariant IDs currently
168
+ observed for each mutation. Multiple IDs mean one mutation violates more than
169
+ one invariant; they do not turn the finite corpus into completeness evidence.
170
+
171
+ <!-- verifier-faults:start -->
172
+ | Fault | Observed invariant IDs |
173
+ | --- | --- |
174
+ | `add_lookahead` | V1, V2 |
175
+ | `remove_item` | V1, V2 |
176
+ | `remove_lookahead` | V2 |
177
+ | `move_item_dot` | V1, V2 |
178
+ | `remove_transition` | V4 |
179
+ | `redirect_transition` | V1 |
180
+ | `remove_action` | V1 |
181
+ | `redirect_shift` | V1 |
182
+ | `replace_reduction` | V1 |
183
+ | `remove_goto` | V1 |
184
+ | `redirect_goto` | V1 |
185
+ | `add_default` | V4 |
186
+ | `remove_default` | V1 |
187
+ | `remove_error_mask` | V4 |
188
+ | `remove_conflict` | V8 |
189
+ | `duplicate_conflict` | V8 |
190
+ | `redirect_conflict_shift` | V8 |
191
+ | `change_conflict_choice` | V8 |
192
+ | `add_unreachable_state` | V1, V6 |
193
+ | `epsilon_cycle` | V1, V4, V7 |
194
+ <!-- verifier-faults:end -->
195
+
196
+ The corpus demonstrates detection of these twenty constructed, structurally
197
+ valid mutations on its committed grammars and construction harness. It does
198
+ not establish that all corruptions, all combinations of faults, or faults in
199
+ the TCB are detected.
data/docs/workloads.md ADDED
@@ -0,0 +1,132 @@
1
+ # Public workload and problem registry
2
+
3
+ [`workloads.yml`](workloads.yml) is the machine-readable authority for workload
4
+ identity, source and license evidence, structural measurements, known problems,
5
+ workarounds, and benchmark eligibility. It is a planning registry, not a claim
6
+ that every grammar is fully supported or that every eligible scope has a
7
+ published result.
8
+
9
+ ## Source classes
10
+
11
+ The `classification` field prevents unlike evidence from being combined:
12
+
13
+ | Class | Meaning |
14
+ | --- | --- |
15
+ | `public_real` | A public third-party application grammar with an exact repository revision. |
16
+ | `external_real` | A public third-party grammar used by the download-only Bison import gate. |
17
+ | `repository_real` | A production Ibex workload, currently the self-hosted frontend. |
18
+ | `repository_synthetic` | A repository-authored correctness fixture; it is not adoption or public-language evidence. |
19
+
20
+ In particular, the gallery is `repository_synthetic`. Its results can support
21
+ correctness, fuzzing, and verifier claims, but cannot by themselves establish a
22
+ benefit for Namae, BCDice, Nokogiri, CRuby, jq, PHP, or PostgreSQL. The three
23
+ `public_real` workloads may support only the scopes listed in their eligibility
24
+ records and only after the benchmark's checkout and behavior checks pass.
25
+
26
+ ## Counting contract
27
+
28
+ `ibex-normalized-lalr-v1` parses the exact pinned bytes in their admitted mode,
29
+ normalizes them to Grammar IR, counts user productions and all normalized
30
+ terminals (including `$eof` and `error`), then builds the direct LALR automaton
31
+ and counts states and unresolved conflicts. Bison-family sources are first
32
+ processed by the Ibex importer, which strips actions and reports unsupported
33
+ directives.
34
+
35
+ `measured` means that the complete grammar admitted by that method was counted.
36
+ `not_measured` requires a reason and carries no numeric value. The pinned current
37
+ CRuby Lrama grammar has 22 structural import gaps, so its partial importer
38
+ figures are deliberately not promoted to production, token, state, or conflict
39
+ counts.
40
+
41
+ The registry validator recomputes repository-owned grammar counts, cross-checks
42
+ the three public identities, grammar digests, production/state/token counts,
43
+ and conflicts against
44
+ [`benchmark/public_workloads.json`](../benchmark/public_workloads.json), and
45
+ cross-checks Bison identities and every structurally complete expected metric,
46
+ including tokens, against
47
+ [`tool/quality/bison_external.rb`](../tool/quality/bison_external.rb). It does
48
+ not download third-party source in ordinary CI.
49
+
50
+ Remote source, license, and permission records have a second reviewed binding in
51
+ [`tool/quality/workloads/evidence.yml`](../tool/quality/workloads/evidence.yml).
52
+ The validator requires exact owner/project/revision/path-derived GitHub
53
+ locators, license expressions, evidence digests, and classification-appropriate
54
+ permission states to match that fixture. Repository-owned evidence is instead
55
+ checked against both the current file and its pinned Git object.
56
+
57
+ ## Registered workloads
58
+
59
+ Counts are production/state/token. `n/m` means `not_measured`, not zero.
60
+
61
+ | Stable workload ID | Class | Grammar | Counts | Conflicts SR/RR | Benchmark status and scope |
62
+ | --- | --- | --- | ---: | ---: | --- |
63
+ | `bcdice-command-parser` | `public_real` | BCDice command parser | 34/56/19 | 2/0 | eligible: public generation/runtime |
64
+ | `bison-gnu-calc` | `external_real` | GNU Bison C calculator | 13/22/11 | 0/0 | diagnostic only: Bison import compatibility |
65
+ | `bison-jq-parser` | `external_real` | jq parser | 167/311/100 | 408/0 | diagnostic only: import/conflict analysis |
66
+ | `bison-php-parser` | `external_real` | PHP Zend language parser | 635/1203/185 | 0/0 | diagnostic only: import/scale construction |
67
+ | `bison-postgresql-parser` | `external_real` | PostgreSQL backend SQL grammar | 3640/6942/562 | 0/0 | diagnostic only: import/scale construction |
68
+ | `bison-ruby-bison-era` | `external_real` | CRuby Bison-era parse.y | 781/1303/158 | 0/0 | diagnostic only: import/external state comparison |
69
+ | `bison-ruby-current-lrama` | `external_real` | Pinned current CRuby Lrama parse.y | n/m | n/m | ineligible: structurally incomplete import |
70
+ | `gallery-calc` | `repository_synthetic` | Calculator fixture | 7/15/9 | 0/0 | eligible: correctness/fuzzing/verification |
71
+ | `gallery-json` | `repository_synthetic` | JSON fixture | 17/27/13 | 0/0 | eligible: correctness/fuzzing/verification |
72
+ | `gallery-sql-lite` | `repository_synthetic` | SQL-subset fixture | 14/26/14 | 0/0 | eligible: correctness/fuzzing/verification |
73
+ | `ibex-frontend` | `repository_real` | Production self-hosted grammar | 146/227/60 | 0/0 | eligible: self-host/regression |
74
+ | `namae-parser` | `public_real` | Namae name parser | 51/78/12 | 0/0 | eligible: public generation/runtime |
75
+ | `nokogiri-css-parser` | `public_real` | Nokogiri CSS parser | 81/117/32 | 0/1 | eligible: public generation/runtime |
76
+
77
+ The exact owner/project, full revision, path, source SHA-256, license expression
78
+ and evidence digest, public-source permission evidence, feature inventory,
79
+ current pain, current workaround, and eligibility reasons live in the YAML
80
+ record. Third-party license locators include the full pinned revision; their
81
+ digests were calculated from those exact bytes. The registry records evidence
82
+ and does not replace a project's license terms or legal review.
83
+
84
+ ## Stable problem IDs
85
+
86
+ Future design and profiling work should cite a problem and at least one workload
87
+ ID instead of saying only that a change helps “real grammars.”
88
+
89
+ | Stable problem ID | Current evidence boundary |
90
+ | --- | --- |
91
+ | `problem-bison-dialect-coverage` | Every pinned Bison-family import reports at least one unsupported directive; current CRuby has structural gaps. |
92
+ | `problem-conflict-volume` | `bison-jq-parser` has 408 unresolved shift/reduce conflicts in the measured imported direct-LALR automaton. This is not a claim about jq's production parser behavior. |
93
+ | `problem-public-runtime-performance` | The evidence-pending historical projection retains slower cold-generation and new-instance rows for the three `public_real` workloads. |
94
+
95
+ For example, a direct-IELR proposal can cite
96
+ `problem-conflict-volume` + `bison-jq-parser`, but it must still establish that
97
+ the imported conflicts are semantically meaningful before claiming an
98
+ application benefit. A runtime optimization can cite
99
+ `problem-public-runtime-performance` plus the affected public workload IDs and
100
+ must publish a new environment-bound comparison artifact before making a
101
+ current performance claim.
102
+
103
+ The H005 [construction profile](construction-profiling.md) consumes these exact
104
+ identities and keeps unavailable public checkouts as `not_run`. Synthetic and
105
+ repository-real construction observations never stand in for third-party
106
+ evidence.
107
+
108
+ ## Updating the registry
109
+
110
+ Run:
111
+
112
+ ```sh
113
+ bundle exec rake quality:workloads
114
+ bundle exec ruby -Itest test/quality/workloads_test.rb
115
+ ```
116
+
117
+ For a repository grammar, update its revision to a commit that already contains
118
+ the recorded source bytes, update its digest, and let the validator recompute
119
+ counts. The initial repository entries intentionally use pre-registry revision
120
+ `d901b787c7e10c1ab3344ac0156f802ab29ad207`, avoiding a self-referential
121
+ registry commit.
122
+
123
+ For a public benchmark grammar, change
124
+ `benchmark/public_workloads.json` and this registry together. For a Bison input,
125
+ change the source constant, digest, expected measurements, exact-revision
126
+ license evidence, and registry together. Any remote source/license change also
127
+ requires an explicitly reviewed update to `tool/quality/workloads/evidence.yml`.
128
+ When a pinned public checkout is supplied, the benchmark recomputes and rejects
129
+ drift in all five structural metric families. A moving branch, tag without a
130
+ resolved commit, short SHA, missing/changed local file, digest mismatch,
131
+ unexplained numeric placeholder, or eligible record without complete count,
132
+ license, and permission evidence fails the quality gate.
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ # steep:ignore:start
5
+
6
+ # The iterative SCC implementation keeps all graph bookkeeping in one pass.
7
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/BlockLength
8
+
9
+ module Ibex
10
+ module Analysis
11
+ # Computes the transitive bit-set closure used by the LR lookahead
12
+ # algorithms. The implementation is iterative so a large grammar cannot
13
+ # exhaust Ruby's call stack merely because its dependency graph is deep.
14
+ module Digraph
15
+ module_function
16
+
17
+ # @rbs (Array[Integer] initial, Array[Array[Integer]] edges) -> Array[Integer]
18
+ def closure(initial, edges)
19
+ raise ArgumentError, "digraph edge count does not match values" unless initial.length == edges.length
20
+
21
+ values = initial.dup
22
+ components = strongly_connected_components(edges)
23
+ component_edges = Array.new(components.length) { [] }
24
+ component_for = Array.new(edges.length)
25
+ components.each_with_index do |members, component_id|
26
+ members.each { |vertex| component_for[vertex] = component_id }
27
+ end
28
+ edges.each_with_index do |successors, vertex|
29
+ source = component_for.fetch(vertex)
30
+ successors.each do |successor|
31
+ target = component_for.fetch(successor)
32
+ component_edges[source] << target if source != target
33
+ end
34
+ end
35
+ component_edges.each(&:uniq!)
36
+
37
+ order = topological_order(component_edges)
38
+ order.reverse_each do |component_id|
39
+ members = components.fetch(component_id)
40
+ merged = members.reduce(0) { |bits, vertex| bits | values.fetch(vertex) }
41
+ component_edges.fetch(component_id).each do |successor|
42
+ merged |= values.fetch(components.fetch(successor).first)
43
+ end
44
+ members.each { |vertex| values[vertex] = merged }
45
+ end
46
+ values
47
+ end
48
+
49
+ # @rbs (Array[Array[Integer]] edges) -> Array[Array[Integer]]
50
+ def strongly_connected_components(edges)
51
+ index = 0
52
+ indexes = Array.new(edges.length)
53
+ lowlinks = Array.new(edges.length)
54
+ on_stack = Array.new(edges.length, false)
55
+ stack = []
56
+ components = []
57
+ visit = lambda do |root|
58
+ frames = [[root, 0, false]]
59
+ until frames.empty?
60
+ vertex, offset, entered = frames[-1]
61
+ unless entered
62
+ indexes[vertex] = index
63
+ lowlinks[vertex] = index
64
+ index += 1
65
+ stack << vertex
66
+ on_stack[vertex] = true
67
+ frames[-1][2] = true
68
+ end
69
+
70
+ successors = edges.fetch(vertex)
71
+ if offset < successors.length
72
+ successor = successors.fetch(offset)
73
+ frames[-1][1] += 1
74
+ if indexes[successor].nil?
75
+ frames << [successor, 0, false]
76
+ elsif on_stack[successor]
77
+ lowlinks[vertex] = [lowlinks[vertex], indexes[successor]].min
78
+ end
79
+ next
80
+ end
81
+
82
+ if lowlinks[vertex] == indexes[vertex]
83
+ component = []
84
+ loop do
85
+ member = stack.pop
86
+ on_stack[member] = false
87
+ component << member
88
+ break if member == vertex
89
+ end
90
+ components << component.sort
91
+ end
92
+ frames.pop
93
+ next if frames.empty?
94
+
95
+ parent = frames[-1][0]
96
+ lowlinks[parent] = [lowlinks[parent], lowlinks[vertex]].min
97
+ end
98
+ end
99
+ edges.each_index { |vertex| visit.call(vertex) if indexes[vertex].nil? }
100
+ components
101
+ end
102
+ private_class_method :strongly_connected_components
103
+
104
+ # @rbs (Array[Array[Integer]]) -> Array[Integer]
105
+ def topological_order(edges)
106
+ indegree = Array.new(edges.length, 0)
107
+ edges.each { |successors| successors.each { |successor| indegree[successor] += 1 } }
108
+ queue = indegree.each_index.select { |vertex| indegree[vertex].zero? }
109
+ order = []
110
+ until queue.empty?
111
+ vertex = queue.shift
112
+ order << vertex
113
+ edges.fetch(vertex).each do |successor|
114
+ indegree[successor] -= 1
115
+ queue << successor if indegree[successor].zero?
116
+ end
117
+ end
118
+ raise Ibex::Error, "digraph contains a cyclic component graph" unless order.length == edges.length
119
+
120
+ order
121
+ end
122
+ private_class_method :topological_order
123
+ end
124
+ end
125
+ end
126
+
127
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/BlockLength
128
+ # steep:ignore:end
data/lib/ibex/analysis.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "analysis/sets"
4
+ require_relative "analysis/digraph"
4
5
 
5
6
  module Ibex
6
7
  module Analysis