domainforge 0.13.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 (481) hide show
  1. package/.cargo/config.toml +6 -0
  2. package/.claude/settings.local.json +18 -0
  3. package/.coderabbit.yml +43 -0
  4. package/.codex/skills/release-management/SKILL.md +151 -0
  5. package/.codex/skills/release-management/agents/openai.yaml +4 -0
  6. package/.github/actions/decrypt-secrets/action.yml +121 -0
  7. package/.github/agents/Coder.agent.md +97 -0
  8. package/.github/agents/DeepResearch.agent.md +61 -0
  9. package/.github/chatmodes/tdd.vibepro.chatmode.md +1183 -0
  10. package/.github/copilot-instructions.md +13 -0
  11. package/.github/dependabot.yml +68 -0
  12. package/.github/workflows/README.md +165 -0
  13. package/.github/workflows/ci.yml +335 -0
  14. package/.github/workflows/dependabot-automerge.yml +114 -0
  15. package/.github/workflows/dependency-review.yml +27 -0
  16. package/.github/workflows/deploy.yml +87 -0
  17. package/.github/workflows/prepare-release.yml +168 -0
  18. package/.github/workflows/release-crates.yml +42 -0
  19. package/.github/workflows/release-npm.yml +137 -0
  20. package/.github/workflows/release-please.yml +29 -0
  21. package/.github/workflows/release-pypi.yml +96 -0
  22. package/.gitkeep +1 -0
  23. package/.release-please-manifest.json +5 -0
  24. package/.sea-registry.toml +10 -0
  25. package/.serena/project.yml +133 -0
  26. package/.sops.yaml +10 -0
  27. package/AGENTS.md +216 -0
  28. package/CHANGELOG.md +400 -0
  29. package/CLAUDE.md +62 -0
  30. package/CONTRIBUTING.md +323 -0
  31. package/Cargo.lock +3612 -0
  32. package/Cargo.toml +12 -0
  33. package/LICENSE +201 -0
  34. package/README.md +660 -0
  35. package/README_PYTHON.md +256 -0
  36. package/README_TYPESCRIPT.md +305 -0
  37. package/README_WASM.md +329 -0
  38. package/RELEASE_NOTES.md +41 -0
  39. package/bun.lock +378 -0
  40. package/bunfig.toml +11 -0
  41. package/check_output.txt +83 -0
  42. package/clippy_output.txt +80 -0
  43. package/commitlint.config.cjs +8 -0
  44. package/deny.toml +42 -0
  45. package/devbox.json +14 -0
  46. package/devbox.lock +76 -0
  47. package/docs/RELEASE_PROCESS.md +360 -0
  48. package/docs/diagnostics.md +161 -0
  49. package/docs/doc_guidelines.md +53 -0
  50. package/docs/explanations/README.md +21 -0
  51. package/docs/explanations/architecture-overview.md +109 -0
  52. package/docs/explanations/cross-language-binding-strategy.md +68 -0
  53. package/docs/explanations/graph-store-design.md +47 -0
  54. package/docs/explanations/performance-benchmarks.md +63 -0
  55. package/docs/explanations/policy-evaluation-logic.md +106 -0
  56. package/docs/explanations/semantic-modeling-concepts.md +109 -0
  57. package/docs/explanations/three-valued-logic.md +66 -0
  58. package/docs/explanations/versioning-strategy.md +45 -0
  59. package/docs/governance.md +168 -0
  60. package/docs/how-tos/README.md +46 -0
  61. package/docs/how-tos/ci-cd-validation.md +93 -0
  62. package/docs/how-tos/create-custom-units.md +125 -0
  63. package/docs/how-tos/define-policies.md +119 -0
  64. package/docs/how-tos/export-to-calm.md +110 -0
  65. package/docs/how-tos/export-to-protobuf.md +312 -0
  66. package/docs/how-tos/extend-grammar.md +133 -0
  67. package/docs/how-tos/generate-rdf-turtle.md +106 -0
  68. package/docs/how-tos/import-from-calm.md +114 -0
  69. package/docs/how-tos/import-from-sbvr.md +249 -0
  70. package/docs/how-tos/install-cli.md +126 -0
  71. package/docs/how-tos/parse-sea-files.md +132 -0
  72. package/docs/how-tos/policy-evaluation-modes.md +30 -0
  73. package/docs/how-tos/run-cross-language-tests.md +115 -0
  74. package/docs/how-tos/troubleshoot-napi-builds.md +55 -0
  75. package/docs/how-tos/use-modules-imports.md +285 -0
  76. package/docs/index.md +13 -0
  77. package/docs/plans/canonical-normalizer.md +121 -0
  78. package/docs/plans/cd_improvement.md +112 -0
  79. package/docs/plans/cli-ast.md +29 -0
  80. package/docs/plans/expression-bindings-and-normalizer-integration.md +174 -0
  81. package/docs/plans/protobuf_advanced_features_plan.md +597 -0
  82. package/docs/plans/protobuf_plan.yml +525 -0
  83. package/docs/plans/refactor_dsl_architecture.md +131 -0
  84. package/docs/plans/release-plan.md +163 -0
  85. package/docs/plans/sea_fmt_implementation_plan.md +516 -0
  86. package/docs/playbooks/README.md +18 -0
  87. package/docs/playbooks/adding-new-primitive.md +68 -0
  88. package/docs/playbooks/debugging-parser-failures.md +42 -0
  89. package/docs/playbooks/local-release-preparation.md +139 -0
  90. package/docs/playbooks/migrating-schema-versions.md +43 -0
  91. package/docs/playbooks/onboarding-contributors.md +64 -0
  92. package/docs/playbooks/releasing-beta.md +86 -0
  93. package/docs/playbooks/secret-management.md +64 -0
  94. package/docs/reference/README.md +199 -0
  95. package/docs/reference/ast-json-api.md +427 -0
  96. package/docs/reference/calm-mapping.md +519 -0
  97. package/docs/reference/cli-commands.md +588 -0
  98. package/docs/reference/configuration.md +202 -0
  99. package/docs/reference/error-codes.md +664 -0
  100. package/docs/reference/generated-artifacts-policy.md +53 -0
  101. package/docs/reference/grammar-spec.md +255 -0
  102. package/docs/reference/primitives-api.md +317 -0
  103. package/docs/reference/protobuf-api.md +426 -0
  104. package/docs/reference/python-api.md +485 -0
  105. package/docs/reference/registry.md +50 -0
  106. package/docs/reference/sea-dsl-ai-cheatsheet.yaml +913 -0
  107. package/docs/reference/security-model.md +74 -0
  108. package/docs/reference/typescript-api.md +508 -0
  109. package/docs/reference/wasm-api.md +420 -0
  110. package/docs/semantic-pack-review.md +144 -0
  111. package/docs/semantic-pack-signing.md +234 -0
  112. package/docs/semantic-packs.md +284 -0
  113. package/docs/specs/ADR-001-sea-dsl-semantic-source-of-truth.md +33 -0
  114. package/docs/specs/ADR-002-projection-first-class-construct.md +50 -0
  115. package/docs/specs/ADR-003-protobuf-projection-target.md +51 -0
  116. package/docs/specs/ADR-004-projection-compatibility-semantics.md +57 -0
  117. package/docs/specs/ADR-005-multi-language-support-strategy.md +112 -0
  118. package/docs/specs/ADR-006-error-handling-strategy.md +115 -0
  119. package/docs/specs/ADR-007-policy-evaluation-engine.md +95 -0
  120. package/docs/specs/ADR-008-knowledge-graph-integration.md +90 -0
  121. package/docs/specs/ADR-009-module-resolution-strategy.md +115 -0
  122. package/docs/specs/ADR-010-unit-system.md +106 -0
  123. package/docs/specs/PRD-001-sea-projection-framework.md +155 -0
  124. package/docs/specs/PRD-002-sea-cli-tooling.md +169 -0
  125. package/docs/specs/PRD-003-dsl-core-capabilities.md +275 -0
  126. package/docs/specs/README.md +62 -0
  127. package/docs/specs/SDS-001-protobuf-projection-engine.md +451 -0
  128. package/docs/specs/SDS-002-sea-core-architecture.md +268 -0
  129. package/docs/specs/SDS-003-parser-semantic-graph.md +377 -0
  130. package/docs/specs/SDS-004-policy-engine-design.md +362 -0
  131. package/docs/specs/SDS-005-knowledge-graph-module.md +364 -0
  132. package/docs/specs/SDS-006-calm-integration.md +367 -0
  133. package/docs/specs/SDS-007-sbvr-import.md +347 -0
  134. package/docs/templates/template_explanation.md +14 -0
  135. package/docs/templates/template_howto.md +21 -0
  136. package/docs/templates/template_playbook.md +21 -0
  137. package/docs/templates/template_reference.md +17 -0
  138. package/docs/templates/template_tutorial.md +24 -0
  139. package/docs/tutorials/README.md +12 -0
  140. package/docs/tutorials/first-sea-model.md +85 -0
  141. package/docs/tutorials/getting-started.md +98 -0
  142. package/docs/tutorials/python-binding-quickstart.md +107 -0
  143. package/docs/tutorials/typescript-binding-quickstart.md +91 -0
  144. package/docs/tutorials/wasm-in-browser.md +75 -0
  145. package/domainforge-core/CHANGELOG.md +138 -0
  146. package/domainforge-core/Cargo.toml +101 -0
  147. package/domainforge-core/MIGRATING.md +32 -0
  148. package/domainforge-core/README.md +197 -0
  149. package/domainforge-core/benchmark_results.txt +51 -0
  150. package/domainforge-core/build.rs +6 -0
  151. package/domainforge-core/deny.toml +31 -0
  152. package/domainforge-core/docs/specs/projections/sbvr_kg_mapping.md +43 -0
  153. package/domainforge-core/examples/basic.sea +7 -0
  154. package/domainforge-core/examples/cli/import_export_workflow.sh +38 -0
  155. package/domainforge-core/examples/cli/validate_example.sh +30 -0
  156. package/domainforge-core/examples/evolution_semantics.sea +31 -0
  157. package/domainforge-core/examples/parser_demo.rs +203 -0
  158. package/domainforge-core/grammar/sea.pest +408 -0
  159. package/domainforge-core/schemas/calm-v1.schema.json +170 -0
  160. package/domainforge-core/schemas/shacl/sea_shapes.ttl +19 -0
  161. package/domainforge-core/src/authority/compiler.rs +309 -0
  162. package/domainforge-core/src/authority/environment.rs +203 -0
  163. package/domainforge-core/src/authority/error.rs +164 -0
  164. package/domainforge-core/src/authority/fact_resolver.rs +224 -0
  165. package/domainforge-core/src/authority/mod.rs +25 -0
  166. package/domainforge-core/src/authority/pack.rs +133 -0
  167. package/domainforge-core/src/authority/policy.rs +224 -0
  168. package/domainforge-core/src/authority/resolver.rs +446 -0
  169. package/domainforge-core/src/authority/trace.rs +217 -0
  170. package/domainforge-core/src/authority/transform.rs +168 -0
  171. package/domainforge-core/src/authority/types.rs +617 -0
  172. package/domainforge-core/src/bin/domainforge.rs +25 -0
  173. package/domainforge-core/src/calm/export.rs +538 -0
  174. package/domainforge-core/src/calm/import.rs +1220 -0
  175. package/domainforge-core/src/calm/mod.rs +9 -0
  176. package/domainforge-core/src/calm/models.rs +108 -0
  177. package/domainforge-core/src/calm/sbvr_import.rs +9 -0
  178. package/domainforge-core/src/cli/authority.rs +149 -0
  179. package/domainforge-core/src/cli/format.rs +85 -0
  180. package/domainforge-core/src/cli/import.rs +133 -0
  181. package/domainforge-core/src/cli/mod.rs +64 -0
  182. package/domainforge-core/src/cli/normalize.rs +180 -0
  183. package/domainforge-core/src/cli/pack.rs +904 -0
  184. package/domainforge-core/src/cli/parse.rs +112 -0
  185. package/domainforge-core/src/cli/project.rs +294 -0
  186. package/domainforge-core/src/cli/registry.rs +41 -0
  187. package/domainforge-core/src/cli/test.rs +12 -0
  188. package/domainforge-core/src/cli/validate.rs +195 -0
  189. package/domainforge-core/src/cli/validate_kg.rs +80 -0
  190. package/domainforge-core/src/concept_id.rs +89 -0
  191. package/domainforge-core/src/error/diagnostics.rs +426 -0
  192. package/domainforge-core/src/error/fuzzy.rs +253 -0
  193. package/domainforge-core/src/error/mod.rs +13 -0
  194. package/domainforge-core/src/formatter/comments.rs +223 -0
  195. package/domainforge-core/src/formatter/config.rs +114 -0
  196. package/domainforge-core/src/formatter/mod.rs +22 -0
  197. package/domainforge-core/src/formatter/printer.rs +906 -0
  198. package/domainforge-core/src/graph/mod.rs +858 -0
  199. package/domainforge-core/src/graph/to_ast.rs +66 -0
  200. package/domainforge-core/src/kg.rs +1476 -0
  201. package/domainforge-core/src/kg_import.rs +251 -0
  202. package/domainforge-core/src/lib.rs +203 -0
  203. package/domainforge-core/src/module/mod.rs +1 -0
  204. package/domainforge-core/src/module/resolver.rs +260 -0
  205. package/domainforge-core/src/parser/ast.rs +2919 -0
  206. package/domainforge-core/src/parser/ast_convert.rs +494 -0
  207. package/domainforge-core/src/parser/ast_schema.rs +491 -0
  208. package/domainforge-core/src/parser/error.rs +291 -0
  209. package/domainforge-core/src/parser/lint.rs +39 -0
  210. package/domainforge-core/src/parser/mod.rs +193 -0
  211. package/domainforge-core/src/parser/printer.rs +702 -0
  212. package/domainforge-core/src/parser/profiles.rs +71 -0
  213. package/domainforge-core/src/parser/string_utils.rs +138 -0
  214. package/domainforge-core/src/patterns.rs +68 -0
  215. package/domainforge-core/src/policy/core.rs +1148 -0
  216. package/domainforge-core/src/policy/expression.rs +399 -0
  217. package/domainforge-core/src/policy/mod.rs +18 -0
  218. package/domainforge-core/src/policy/normalize.rs +1028 -0
  219. package/domainforge-core/src/policy/quantifier.rs +940 -0
  220. package/domainforge-core/src/policy/three_valued.rs +140 -0
  221. package/domainforge-core/src/policy/three_valued_microbench.rs +104 -0
  222. package/domainforge-core/src/policy/type_inference.rs +67 -0
  223. package/domainforge-core/src/policy/violation.rs +36 -0
  224. package/domainforge-core/src/primitives/concept_change.rs +61 -0
  225. package/domainforge-core/src/primitives/entity.rs +224 -0
  226. package/domainforge-core/src/primitives/flow.rs +111 -0
  227. package/domainforge-core/src/primitives/instance.rs +93 -0
  228. package/domainforge-core/src/primitives/mapping_contract.rs +50 -0
  229. package/domainforge-core/src/primitives/metric.rs +79 -0
  230. package/domainforge-core/src/primitives/mod.rs +25 -0
  231. package/domainforge-core/src/primitives/projection_contract.rs +50 -0
  232. package/domainforge-core/src/primitives/quantity.rs +56 -0
  233. package/domainforge-core/src/primitives/relation.rs +68 -0
  234. package/domainforge-core/src/primitives/resource.rs +237 -0
  235. package/domainforge-core/src/primitives/resource_instance.rs +88 -0
  236. package/domainforge-core/src/primitives/role.rs +49 -0
  237. package/domainforge-core/src/projection/buf.rs +404 -0
  238. package/domainforge-core/src/projection/contracts.rs +22 -0
  239. package/domainforge-core/src/projection/engine.rs +19 -0
  240. package/domainforge-core/src/projection/mod.rs +16 -0
  241. package/domainforge-core/src/projection/protobuf.rs +3331 -0
  242. package/domainforge-core/src/projection/registry.rs +43 -0
  243. package/domainforge-core/src/python/authority.rs +253 -0
  244. package/domainforge-core/src/python/error.rs +227 -0
  245. package/domainforge-core/src/python/formatter.rs +86 -0
  246. package/domainforge-core/src/python/graph.rs +366 -0
  247. package/domainforge-core/src/python/mod.rs +9 -0
  248. package/domainforge-core/src/python/policy.rs +651 -0
  249. package/domainforge-core/src/python/primitives.rs +796 -0
  250. package/domainforge-core/src/python/registry.rs +98 -0
  251. package/domainforge-core/src/python/semantic_pack.rs +619 -0
  252. package/domainforge-core/src/python/units.rs +96 -0
  253. package/domainforge-core/src/registry/mod.rs +432 -0
  254. package/domainforge-core/src/registry/tests.rs +210 -0
  255. package/domainforge-core/src/sbvr.rs +744 -0
  256. package/domainforge-core/src/semantic_pack/builder.rs +470 -0
  257. package/domainforge-core/src/semantic_pack/canonical_json.rs +184 -0
  258. package/domainforge-core/src/semantic_pack/diagnostics.rs +214 -0
  259. package/domainforge-core/src/semantic_pack/diff.rs +216 -0
  260. package/domainforge-core/src/semantic_pack/mod.rs +31 -0
  261. package/domainforge-core/src/semantic_pack/pack_set.rs +240 -0
  262. package/domainforge-core/src/semantic_pack/resolver.rs +437 -0
  263. package/domainforge-core/src/semantic_pack/review.rs +125 -0
  264. package/domainforge-core/src/semantic_pack/schema.rs +342 -0
  265. package/domainforge-core/src/semantic_pack/signing.rs +105 -0
  266. package/domainforge-core/src/semantic_pack/validator.rs +368 -0
  267. package/domainforge-core/src/semantic_version.rs +140 -0
  268. package/domainforge-core/src/test_utils.rs +12 -0
  269. package/domainforge-core/src/typescript/authority.rs +184 -0
  270. package/domainforge-core/src/typescript/error.rs +146 -0
  271. package/domainforge-core/src/typescript/formatter.rs +76 -0
  272. package/domainforge-core/src/typescript/graph.rs +391 -0
  273. package/domainforge-core/src/typescript/mod.rs +9 -0
  274. package/domainforge-core/src/typescript/policy.rs +564 -0
  275. package/domainforge-core/src/typescript/primitives.rs +784 -0
  276. package/domainforge-core/src/typescript/registry.rs +88 -0
  277. package/domainforge-core/src/typescript/semantic_pack.rs +470 -0
  278. package/domainforge-core/src/typescript/units.rs +76 -0
  279. package/domainforge-core/src/units/mod.rs +462 -0
  280. package/domainforge-core/src/uuid_module.rs +42 -0
  281. package/domainforge-core/src/validation_error.rs +818 -0
  282. package/domainforge-core/src/validation_result.rs +30 -0
  283. package/domainforge-core/src/wasm/authority.rs +192 -0
  284. package/domainforge-core/src/wasm/error.rs +145 -0
  285. package/domainforge-core/src/wasm/formatter.rs +69 -0
  286. package/domainforge-core/src/wasm/graph.rs +471 -0
  287. package/domainforge-core/src/wasm/mod.rs +16 -0
  288. package/domainforge-core/src/wasm/policy.rs +607 -0
  289. package/domainforge-core/src/wasm/primitives.rs +295 -0
  290. package/domainforge-core/src/wasm/semantic_pack.rs +471 -0
  291. package/domainforge-core/src/wasm/units.rs +62 -0
  292. package/domainforge-core/std/aws.sea +6 -0
  293. package/domainforge-core/std/core.sea +6 -0
  294. package/domainforge-core/std/http.sea +27 -0
  295. package/domainforge-core/tests/aggregation_enhanced_tests.rs +162 -0
  296. package/domainforge-core/tests/aggregation_eval_tests.rs +248 -0
  297. package/domainforge-core/tests/aggregation_integration_tests.rs +379 -0
  298. package/domainforge-core/tests/aggregation_parser_tests.rs +92 -0
  299. package/domainforge-core/tests/aggregation_tests.rs +102 -0
  300. package/domainforge-core/tests/authority_conformance_tests.rs +1173 -0
  301. package/domainforge-core/tests/calm_round_trip_tests.rs +283 -0
  302. package/domainforge-core/tests/calm_schema_validation_tests.rs +137 -0
  303. package/domainforge-core/tests/cast_operator_tests.rs +85 -0
  304. package/domainforge-core/tests/cli_binary_check.rs +37 -0
  305. package/domainforge-core/tests/cli_import_tests.rs +291 -0
  306. package/domainforge-core/tests/cli_path_traversal_tests.rs +124 -0
  307. package/domainforge-core/tests/cli_tests.rs +63 -0
  308. package/domainforge-core/tests/diagnostics_tests.rs +203 -0
  309. package/domainforge-core/tests/dimension_unit_tests.rs +80 -0
  310. package/domainforge-core/tests/entity_tests.rs +69 -0
  311. package/domainforge-core/tests/evolution_semantics_tests.rs +157 -0
  312. package/domainforge-core/tests/flow_tests.rs +78 -0
  313. package/domainforge-core/tests/flow_unit_validation_tests.rs +31 -0
  314. package/domainforge-core/tests/graph_integration_tests.rs +218 -0
  315. package/domainforge-core/tests/graph_tests.rs +626 -0
  316. package/domainforge-core/tests/import_parsing_tests.rs +23 -0
  317. package/domainforge-core/tests/instance_integration_tests.rs +98 -0
  318. package/domainforge-core/tests/instance_parsing_tests.rs +58 -0
  319. package/domainforge-core/tests/instance_tests.rs +61 -0
  320. package/domainforge-core/tests/kg_uri_encoding_tests.rs +53 -0
  321. package/domainforge-core/tests/lint_tests.rs +19 -0
  322. package/domainforge-core/tests/metric_tests.rs +143 -0
  323. package/domainforge-core/tests/module_resolution_tests.rs +100 -0
  324. package/domainforge-core/tests/namespace_registry_tests.rs +247 -0
  325. package/domainforge-core/tests/null_handling_tests.rs +26 -0
  326. package/domainforge-core/tests/parser_ast_v3.rs +53 -0
  327. package/domainforge-core/tests/parser_dimension_registry_tests.rs +20 -0
  328. package/domainforge-core/tests/parser_integration_tests.rs +294 -0
  329. package/domainforge-core/tests/parser_metadata_tests.rs +97 -0
  330. package/domainforge-core/tests/parser_resource_domain_only_graph_test.rs +21 -0
  331. package/domainforge-core/tests/parser_resource_limits_tests.rs +122 -0
  332. package/domainforge-core/tests/parser_tests.rs +512 -0
  333. package/domainforge-core/tests/pattern_semantics_tests.rs +87 -0
  334. package/domainforge-core/tests/phase_14_determinism_tests.rs +166 -0
  335. package/domainforge-core/tests/phase_15_validation_error_tests.rs +136 -0
  336. package/domainforge-core/tests/phase_16_unicode_tests.rs +248 -0
  337. package/domainforge-core/tests/phase_17_export_tests.rs +285 -0
  338. package/domainforge-core/tests/phase_17_round_trip_tests.rs +264 -0
  339. package/domainforge-core/tests/policy_tests.rs +635 -0
  340. package/domainforge-core/tests/primitives_integration_tests.rs +151 -0
  341. package/domainforge-core/tests/print_rdf_xml.rs +14 -0
  342. package/domainforge-core/tests/printer_tests.rs +204 -0
  343. package/domainforge-core/tests/profile_tests.rs +35 -0
  344. package/domainforge-core/tests/projection_contracts_tests.rs +154 -0
  345. package/domainforge-core/tests/protobuf_projection_tests.rs +199 -0
  346. package/domainforge-core/tests/quantity_tests.rs +41 -0
  347. package/domainforge-core/tests/rdf_xml_typed_literal_tests.rs +105 -0
  348. package/domainforge-core/tests/registry_schema_tests.rs +33 -0
  349. package/domainforge-core/tests/resource_tests.rs +50 -0
  350. package/domainforge-core/tests/resource_unit_tests.rs +24 -0
  351. package/domainforge-core/tests/roles_relations_tests.rs +61 -0
  352. package/domainforge-core/tests/round_trip_tests.rs +34 -0
  353. package/domainforge-core/tests/runtime_toggle_tests.rs +70 -0
  354. package/domainforge-core/tests/sbvr_fact_schema_tests.rs +60 -0
  355. package/domainforge-core/tests/sbvr_flow_facts_tests.rs +55 -0
  356. package/domainforge-core/tests/sbvr_parsing_tests.rs +53 -0
  357. package/domainforge-core/tests/semantic_pack_alias_resolution.rs +197 -0
  358. package/domainforge-core/tests/semantic_pack_build.rs +302 -0
  359. package/domainforge-core/tests/semantic_pack_consumer_smoke.rs +150 -0
  360. package/domainforge-core/tests/semantic_pack_pack_set.rs +160 -0
  361. package/domainforge-core/tests/semantic_pack_signing.rs +157 -0
  362. package/domainforge-core/tests/semantic_pack_three_valued.rs +250 -0
  363. package/domainforge-core/tests/semantic_pack_validate.rs +196 -0
  364. package/domainforge-core/tests/std_lib_tests.rs +37 -0
  365. package/domainforge-core/tests/temporal_evaluation_tests.rs +159 -0
  366. package/domainforge-core/tests/temporal_semantics_tests.rs +214 -0
  367. package/domainforge-core/tests/three_valued_quantifiers_tests.rs +164 -0
  368. package/domainforge-core/tests/turtle_entity_export_tests.rs +38 -0
  369. package/domainforge-core/tests/turtle_escaping_tests.rs +53 -0
  370. package/domainforge-core/tests/turtle_resource_export_tests.rs +34 -0
  371. package/domainforge-core/tests/type_inference_tests.rs +40 -0
  372. package/domainforge-core/tests/unicode_validation_tests.rs +169 -0
  373. package/domainforge-core/tests/unit_tests.rs +81 -0
  374. package/domainforge-core/tests/validate_tests.rs +38 -0
  375. package/domainforge-core/tests/validation_unit_mismatch_tests.rs +83 -0
  376. package/domainforge-core/tests/wasm_tests.rs +229 -0
  377. package/domainforge-python/CHANGELOG-python.md +12 -0
  378. package/domainforge-python/MIGRATING.md +24 -0
  379. package/domainforge-python/README.md +256 -0
  380. package/domainforge-python/domainforge/__init__.py +95 -0
  381. package/domainforge-python/domainforge/domainforge.pyi +519 -0
  382. package/domainforge-python/pyproject.toml +36 -0
  383. package/domainforge-typescript/CHANGELOG-typescript.md +12 -0
  384. package/domainforge-typescript/LICENSE +201 -0
  385. package/domainforge-typescript/MIGRATING.md +24 -0
  386. package/domainforge-typescript/README.md +305 -0
  387. package/domainforge-typescript/index.d.ts +452 -0
  388. package/domainforge-typescript/index.js +361 -0
  389. package/domainforge-typescript/package.json +60 -0
  390. package/example.js +61 -0
  391. package/examples/browser.html +366 -0
  392. package/examples/namespaces/finance/cashflow.sea +5 -0
  393. package/examples/namespaces/logistics/core.sea +7 -0
  394. package/examples/observability_metrics.sea +38 -0
  395. package/fixtures/semantic_packs/acme_procurement/domain/entities.sea +39 -0
  396. package/fixtures/semantic_packs/acme_procurement/domain/metrics.sea +11 -0
  397. package/fixtures/semantic_packs/acme_procurement/domain/relations.sea +7 -0
  398. package/fixtures/semantic_packs/acme_procurement/domain/resources.sea +9 -0
  399. package/fixtures/semantic_packs/acme_procurement/review/acme.procurement.semantic-review.jsonl +7 -0
  400. package/fixtures/semantic_packs/acme_procurement/tests/ambiguous_vendor_alias.sea +8 -0
  401. package/fixtures/semantic_packs/acme_procurement/tests/deprecated_vendor_alias.sea +8 -0
  402. package/fixtures/semantic_packs/acme_procurement/tests/invalid_relation.sea +3 -0
  403. package/fixtures/semantic_packs/acme_procurement/tests/proposed_concept.sea +8 -0
  404. package/fixtures/semantic_packs/acme_procurement/tests/rejected_concept.sea +8 -0
  405. package/fixtures/semantic_packs/acme_procurement/tests/unit_mismatch.sea +7 -0
  406. package/fixtures/semantic_packs/acme_procurement/tests/unknown_vendor_policy.sea +8 -0
  407. package/fixtures/semantic_packs/acme_procurement/tests/valid_purchase_policy.sea +8 -0
  408. package/index.d.ts +2 -0
  409. package/index.js +8 -0
  410. package/justfile +200 -0
  411. package/lefthook.yml +13 -0
  412. package/lib/validate_native_exports.d.ts +4 -0
  413. package/lib/validate_native_exports.js +12 -0
  414. package/package.json +22 -0
  415. package/pytest.ini +5 -0
  416. package/python/tests/test_registry.py +75 -0
  417. package/python/tests/test_units.py +18 -0
  418. package/release-please-config.json +49 -0
  419. package/requirements-dev.txt +3 -0
  420. package/requirements.txt +3 -0
  421. package/rust-toolchain.toml +3 -0
  422. package/schemas/ast-v1.schema.json +72 -0
  423. package/schemas/ast-v2.schema.json +1200 -0
  424. package/schemas/ast-v3.schema.json +1200 -0
  425. package/schemas/sea-registry.schema.json +45 -0
  426. package/scripts/build-python.sh +37 -0
  427. package/scripts/build-release.sh +279 -0
  428. package/scripts/build-typescript.sh +13 -0
  429. package/scripts/build-wasm.sh +113 -0
  430. package/scripts/bump-version.sh +245 -0
  431. package/scripts/check_unused_test_imports.py +85 -0
  432. package/scripts/ci_tasks.py +379 -0
  433. package/scripts/clear_debug_test.sh +10 -0
  434. package/scripts/create-github-release.sh +262 -0
  435. package/scripts/create-tag.sh +203 -0
  436. package/scripts/find_and_link_test_binary.sh +70 -0
  437. package/scripts/generate-changelog.sh +271 -0
  438. package/scripts/generate-release-notes.sh +205 -0
  439. package/scripts/lint_release_security.py +96 -0
  440. package/scripts/lint_release_workflows.py +82 -0
  441. package/scripts/lint_workflow_gates.py +113 -0
  442. package/scripts/optimized-wasm-build.sh +61 -0
  443. package/scripts/patch_napi_types.py +62 -0
  444. package/scripts/pre-release-check.sh +289 -0
  445. package/scripts/prepare_rust_debug.sh +52 -0
  446. package/scripts/release.sh +373 -0
  447. package/scripts/resolve_rust_binary.py +230 -0
  448. package/scripts/run_commitlint.sh +29 -0
  449. package/scripts/test-all.sh +77 -0
  450. package/scripts/update_launch_program.py +93 -0
  451. package/secrets/README.md +27 -0
  452. package/secrets/secrets.yaml +21 -0
  453. package/test_integration.py +67 -0
  454. package/tests/test_authority.py +328 -0
  455. package/tests/test_ci_tasks.py +143 -0
  456. package/tests/test_expression.py +256 -0
  457. package/tests/test_golden_payment_flow.py +42 -0
  458. package/tests/test_graph.py +127 -0
  459. package/tests/test_instance.py +136 -0
  460. package/tests/test_parser.py +82 -0
  461. package/tests/test_primitives.py +68 -0
  462. package/tests/test_role_relation_parity.py +56 -0
  463. package/tests/test_runtime_toggle.py +156 -0
  464. package/tests/test_semantic_pack.py +639 -0
  465. package/tests/test_three_valued_eval.py +159 -0
  466. package/tsconfig.json +30 -0
  467. package/typescript-tests/advanced.test.ts +165 -0
  468. package/typescript-tests/authority.test.ts +216 -0
  469. package/typescript-tests/expression.test.ts +228 -0
  470. package/typescript-tests/golden-payment-flow.test.ts +51 -0
  471. package/typescript-tests/graph.test.ts +142 -0
  472. package/typescript-tests/native-binding.test.ts +20 -0
  473. package/typescript-tests/primitives.test.ts +88 -0
  474. package/typescript-tests/registry.test.ts +122 -0
  475. package/typescript-tests/role_relation.test.ts +63 -0
  476. package/typescript-tests/runtime_toggle.test.ts +141 -0
  477. package/typescript-tests/semantic-pack.test.ts +556 -0
  478. package/typescript-tests/three_valued_eval.test.ts +135 -0
  479. package/typescript-tests/units.test.ts +36 -0
  480. package/vitest.config.ts +13 -0
  481. package/wasm_demo.html +225 -0
@@ -0,0 +1,163 @@
1
+ # Release Plan: v0.1.0 — DomainForge (SEA DSL)
2
+
3
+ This document outlines the release plan, publishing order, and best practices for publishing the DomainForge artifacts across ecosystems (crates.io, PyPI, npm, and GitHub). Treat this plan as a canonical checklist for future releases.
4
+
5
+ ## Goals
6
+
7
+ - Publish a single, canonical release (v0.1.0) across all publish targets.
8
+ - Maintain cross-language parity and consistent versioning across Rust/Python/TypeScript/WASM packages.
9
+ - Provide a reproducible, documented release process suitable for CI automation.
10
+
11
+ ## Versioning & Manifests
12
+
13
+ - Ensure version parity across:
14
+ - `domainforge-core/Cargo.toml` (Rust)
15
+ - `pyproject.toml` (Python - domainforge)
16
+ - `package.json` (TypeScript - @godspeedai/domainforge)
17
+ - `pkg/package.json` (WASM - @godspeedai/domainforge-wasm)
18
+ - Choose a semantic version (e.g., 0.1.0). All manifests must match before tagging.
19
+ - Where appropriate, add a `CHANGELOG.md` entry summarizing changes in v0.1.0.
20
+
21
+ ## Pre-release Checklist
22
+
23
+ 1. Confirm tests pass locally and in CI:
24
+ - `just rust-test`
25
+ - `just python-test`
26
+ - `just ts-test`
27
+ 2. Ensure the `README.md` no longer contains roadmap or "coming soon" statements; replace with instructions that reflect the current release state.
28
+ 3. Clean up repository: remove or secure plaintext secrets; ensure `secrets/secrets.yaml` is encrypted.
29
+ 4. Create or update `docs/plans/release-plan.md` (this file) and commit.
30
+ 5. Ensure `pyproject.toml`, `domainforge-core/Cargo.toml`, and `package.json` set the new version.
31
+ 6. Add or update `CHANGELOG.md` and verify the package metadata (`license`, `authors`, `keywords`).
32
+ 7. Run a release smoke test locally by building all artifacts (see below).
33
+
34
+ ## Building & Verifying Artifacts Locally
35
+
36
+ - Rust:
37
+
38
+ ```bash
39
+ cargo build -p domainforge-core --release
40
+ cargo test -p domainforge-core
41
+ ```
42
+
43
+ - Python:
44
+
45
+ ```bash
46
+ .venv/bin/python -m maturin build --release -o dist
47
+ .venv/bin/pip install --index-url https://test.pypi.org/simple --extra-index-url https://pypi.org/simple --force-reinstall dist/domainforge-<version>.whl
48
+ python -c "import domainforge; print(domainforge.__version__)"
49
+ ```
50
+
51
+ - TypeScript/NAPI:
52
+
53
+ ```bash
54
+ npm run build # or `just ts-build` (use local binding to `napi-rs` build)
55
+ npm pack
56
+ npm pack --pack-destination ./dist
57
+ ```
58
+
59
+ - WASM (pkg/):
60
+
61
+ ```bash
62
+ cd pkg
63
+ npm pack
64
+ npm pack --pack-destination ../dist
65
+ ```
66
+
67
+ ## Publish Order & Rationale
68
+
69
+ 1. **Publish Rust core crate to crates.io** (`cargo publish`) — optional but recommended if Rust users will consume `domainforge-core` directly.
70
+ - Auth: `CARGO_REGISTRY_TOKEN` set in CI or environment.
71
+ 2. **Publish WASM package** (`@godspeedai/domainforge-wasm`) to npm (pkg/)
72
+ - Auth: `NPM_TOKEN` (or CI secret).
73
+ - Reason: Browser & edge consumers rely on the WASM artifact.
74
+ 3. **Publish TypeScript bindings** (`@godspeedai/domainforge`) to npm
75
+ - Auth: `NPM_TOKEN`.
76
+ - Reason: Node consumers and the TypeScript API should be available for consumption.
77
+ 4. **Publish Python** (`domainforge`) to PyPI (maturin/publish)
78
+ - Auth: `PYPI_API_TOKEN` or `PYPI_TEST_API_TOKEN` for TestPyPI.
79
+ - Reason: Python package distribution typically bundles native wheels; publish last so any native artifacts are stable.
80
+ 5. **Tag and GitHub release**: Create a signed tag `v0.1.0`, push it to the repo, and create a GitHub Release with the changelog and attachments.
81
+ - Use the `gh` CLI to create a release and attach distributables if needed.
82
+
83
+ > Note: The Rust crate's release is optional for downstream build targeting; the Python and TypeScript artifacts bundle the needed native binaries themselves.
84
+
85
+ ## Publishing Commands (CI-friendly)
86
+
87
+ - Rust:
88
+
89
+ ```bash
90
+ cargo publish --manifest-path domainforge-core/Cargo.toml
91
+ ```
92
+
93
+ - WASM (pkg/):
94
+
95
+ ```bash
96
+ cd pkg
97
+ npm publish --access public
98
+ ```
99
+
100
+ - TypeScript (root):
101
+
102
+ ```bash
103
+ npm publish --access public
104
+ ```
105
+
106
+ - Python (maturin):
107
+
108
+ ```bash
109
+ MATURIN_PYPI_TOKEN="$PYPI_API_TOKEN" maturin publish --repository-url https://upload.pypi.org/legacy --non-interactive
110
+ ```
111
+
112
+ ## GitHub Release
113
+
114
+ - Tag locally and push:
115
+
116
+ ```bash
117
+ git tag -a v0.1.0 -m "Release v0.1.0" # optionally sign with -s
118
+ git push origin v0.1.0
119
+ ```
120
+
121
+ - Create release using `gh` (GitHub CLI):
122
+
123
+ ```bash
124
+ gh release create v0.1.0 --title "v0.1.0" --notes-file CHANGELOG.md
125
+ ```
126
+
127
+ ## Post-Release
128
+
129
+ - Update `README.md` to show how to install packages from the package registries.
130
+ - Update any docs that previously said "coming soon".
131
+ - Verify published packages are available:
132
+ - Rust: <https://crates.io/crates/domainforge-core>
133
+ - PyPI: <https://pypi.org/project/domainforge-python/>
134
+ - npm: <https://www.npmjs.com/package/@godspeedai/domainforge>
135
+ - WASM package page
136
+ - Create release notes and highlight breaking changes (if any).
137
+
138
+ ## Rollback Plan
139
+
140
+ 1. For crates.io: Follow crates.io unpublishing policies; prefer yanking vs full-undo.
141
+ 2. For PyPI/NPM: Versions cannot be re-used; republish a new patch version if needed.
142
+ 3. Re-tag in GitHub and push a new release in case of an urgent fix.
143
+
144
+ ## CI and Automation Notes
145
+
146
+ - Ensure CI secrets are configured in GitHub Actions for `CARGO_REGISTRY_TOKEN`, `PYPI_API_TOKEN`, and `NPM_TOKEN`.
147
+ - Use `npm ci` in CI and `--non-interactive` flags for scripts.
148
+ - Keep a `release.yml` workflow that runs on `release/` branch or manual dispatch.
149
+
150
+ ## Checklist
151
+
152
+ - [ ] Confirm version numbers
153
+ - [ ] Run all tests and checks in CI
154
+ - [ ] Update `README.md` to remove roadmap statements
155
+ - [ ] Update `CHANGELOG.md` entries
156
+ - [ ] Create local tag and push
157
+ - [ ] Publish artifacts in order
158
+ - [ ] Create GitHub Release and attach artifacts
159
+ - [ ] Post-release verification
160
+
161
+ ---
162
+
163
+ *Documentation maintained by the release manager.*
@@ -0,0 +1,516 @@
1
+ # SEA Format (`sea fmt`) Implementation Plan
2
+
3
+ **Version:** 1.0
4
+ **Date:** 2025-12-14
5
+ **Status:** Draft
6
+
7
+ ---
8
+
9
+ ## 1. Overview
10
+
11
+ Implement a code formatter for SEA-DSL files that standardizes whitespace, indentation, and ordering while preserving semantics.
12
+
13
+ ### Goals
14
+
15
+ - Pretty-print SEA files with consistent formatting
16
+ - Preserve all semantic content and comments
17
+ - Support configurable indent style (spaces vs tabs, indent width)
18
+ - Idempotent output (formatting already-formatted code produces identical output)
19
+ - Fast enough for editor integration (format-on-save)
20
+
21
+ ---
22
+
23
+ ## 2. Current State
24
+
25
+ The `sea fmt` command currently:
26
+
27
+ - Parses the file to verify syntax validity
28
+ - Returns an error: "Formatting not yet implemented"
29
+
30
+ **File:** `domainforge-core/src/cli/format.rs` (23 lines)
31
+
32
+ ---
33
+
34
+ ## 3. Architecture
35
+
36
+ ### Design Approach: AST-based Formatting
37
+
38
+ ```
39
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
40
+ │ Source Code │ ──► │ Parse │ ──► │ AST │
41
+ └─────────────┘ └─────────────┘ └─────────────┘
42
+
43
+
44
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
45
+ │ Output │ ◄── │ Formatter │ ◄── │ AST + Span │
46
+ └─────────────┘ └─────────────┘ └─────────────┘
47
+ ```
48
+
49
+ ### Key Design Decisions
50
+
51
+ | Decision | Choice | Rationale |
52
+ | ---------- | -------------------------------- | --------------------------------------- |
53
+ | Strategy | AST-based (not regex/line-based) | Semantic awareness, handles edge cases |
54
+ | Comments | Preserve via span information | Comments are critical for documentation |
55
+ | Ordering | Preserve declaration order | User-defined order is intentional |
56
+ | Whitespace | Normalize to configured style | Main formatter benefit |
57
+
58
+ ---
59
+
60
+ ## 4. Proposed Changes
61
+
62
+ ### Phase 1: Core Formatter Module
63
+
64
+ #### [NEW] `domainforge-core/src/formatter/mod.rs`
65
+
66
+ ```rust
67
+ pub mod config;
68
+ pub mod printer;
69
+
70
+ pub use config::FormatConfig;
71
+ pub use printer::Formatter;
72
+ ```
73
+
74
+ #### [NEW] `domainforge-core/src/formatter/config.rs`
75
+
76
+ Formatter configuration:
77
+
78
+ ```rust
79
+ pub struct FormatConfig {
80
+ pub indent_style: IndentStyle, // Spaces or Tabs
81
+ pub indent_width: usize, // Default: 4
82
+ pub max_line_width: usize, // Default: 100
83
+ pub trailing_newline: bool, // Default: true
84
+ pub preserve_comments: bool, // Default: true
85
+ }
86
+
87
+ pub enum IndentStyle {
88
+ Spaces,
89
+ Tabs,
90
+ }
91
+
92
+ impl Default for FormatConfig {
93
+ fn default() -> Self {
94
+ Self {
95
+ indent_style: IndentStyle::Spaces,
96
+ indent_width: 4,
97
+ max_line_width: 100,
98
+ trailing_newline: true,
99
+ preserve_comments: true,
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ #### [NEW] `domainforge-core/src/formatter/printer.rs`
106
+
107
+ Core formatter logic:
108
+
109
+ ```rust
110
+ pub struct Formatter {
111
+ config: FormatConfig,
112
+ output: String,
113
+ indent_level: usize,
114
+ }
115
+
116
+ impl Formatter {
117
+ pub fn format(source: &str, config: FormatConfig) -> Result<String, FormatError>;
118
+
119
+ fn format_file_header(&mut self, meta: &FileMetadata);
120
+ fn format_declaration(&mut self, node: &AstNode);
121
+ fn format_entity(&mut self, name: &str, version: Option<&str>, annotations: &HashMap, domain: Option<&str>);
122
+ fn format_resource(&mut self, ...);
123
+ fn format_flow(&mut self, ...);
124
+ fn format_policy(&mut self, ...);
125
+ fn format_expression(&mut self, expr: &Expression);
126
+ // ... one method per declaration type
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ### Phase 2: Comment Preservation
133
+
134
+ #### [MODIFY] `domainforge-core/grammar/sea.pest`
135
+
136
+ Update COMMENT rule to capture (not discard):
137
+
138
+ ```diff
139
+ -COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }
140
+ +COMMENT = { "//" ~ (!"\n" ~ ANY)* }
141
+ ```
142
+
143
+ #### [MODIFY] `domainforge-core/src/parser/ast.rs`
144
+
145
+ Add comment attachment to AST nodes:
146
+
147
+ ```rust
148
+ pub struct CommentedNode<T> {
149
+ pub node: T,
150
+ pub leading_comments: Vec<String>,
151
+ pub trailing_comment: Option<String>,
152
+ }
153
+ ```
154
+
155
+ ---
156
+
157
+ ### Phase 3: CLI Integration
158
+
159
+ #### [MODIFY] `domainforge-core/src/cli/format.rs`
160
+
161
+ ```rust
162
+ use crate::formatter::{FormatConfig, Formatter};
163
+
164
+ #[derive(Parser)]
165
+ pub struct FormatArgs {
166
+ pub file: PathBuf,
167
+
168
+ #[arg(long, default_value = "stdout")]
169
+ pub out: Output,
170
+
171
+ #[arg(long, default_value = "4")]
172
+ pub indent_width: usize,
173
+
174
+ #[arg(long)]
175
+ pub use_tabs: bool,
176
+
177
+ #[arg(long)]
178
+ pub check: bool, // Exit 1 if file would change (for CI)
179
+ }
180
+
181
+ pub fn run(args: FormatArgs) -> Result<()> {
182
+ let source = read_to_string(&args.file)?;
183
+
184
+ let config = FormatConfig {
185
+ indent_width: args.indent_width,
186
+ indent_style: if args.use_tabs { IndentStyle::Tabs } else { IndentStyle::Spaces },
187
+ ..Default::default()
188
+ };
189
+
190
+ let formatted = Formatter::format(&source, config)?;
191
+
192
+ if args.check {
193
+ if source != formatted {
194
+ anyhow::bail!("File would be reformatted: {}", args.file.display());
195
+ }
196
+ } else {
197
+ match args.out {
198
+ Output::Stdout => println!("{}", formatted),
199
+ Output::File(path) => write(path, formatted)?,
200
+ }
201
+ }
202
+
203
+ Ok(())
204
+ }
205
+ ```
206
+
207
+ ---
208
+
209
+ ## 5. Formatting Rules
210
+
211
+ ### File Structure
212
+
213
+ ```
214
+ // Header annotations (in order: namespace, version, owner, profile)
215
+ @namespace "com.example"
216
+ @version "1.0.0"
217
+
218
+ // Imports (sorted alphabetically by path)
219
+ import { Entity } from "common.sea"
220
+ import { Resource } from "resources.sea"
221
+
222
+ // Declarations (preserved order)
223
+ Entity "Name" in domain
224
+
225
+ Resource "Name" units in domain
226
+
227
+ Flow "Resource" from "A" to "B" quantity 100
228
+ ```
229
+
230
+ ### Indentation Rules
231
+
232
+ | Context | Indentation |
233
+ | ----------------------- | ------------------- |
234
+ | Top-level declarations | 0 |
235
+ | Instance body | 1 level |
236
+ | Relation fields | 1 level |
237
+ | Mapping/Projection body | 1 level |
238
+ | Policy expression | continuation indent |
239
+
240
+ ### Spacing Rules
241
+
242
+ | Pattern | Rule |
243
+ | ---------------- | ----------------- |
244
+ | After keywords | Single space |
245
+ | Around operators | Single space |
246
+ | After colons | Single space |
247
+ | Before braces | Single space |
248
+ | Empty lines | Max 1 consecutive |
249
+
250
+ ---
251
+
252
+ ## 6. Implementation Phases
253
+
254
+ ### Phase 1: Basic Formatting (MVP) ✅ COMPLETE
255
+
256
+ - [x] Create formatter module structure
257
+ - [x] Implement `FormatConfig`
258
+ - [x] Implement basic `Formatter` with entity, resource, flow support
259
+ - [x] Wire up CLI
260
+
261
+ ### Phase 2: Full Declaration Support ✅ COMPLETE
262
+
263
+ - [x] Add all declaration types (14 total)
264
+ - [x] Add expression formatting
265
+ - [x] Handle complex nested expressions
266
+
267
+ ### Phase 3: Comment Preservation ✅ COMPLETE
268
+
269
+ - [x] ~~Modify grammar~~ Extra module to extract comments without grammar changes
270
+ - [x] Track file header comments separately
271
+ - [x] Preserve file header comments in output
272
+ - [ ] Inline declaration comments (future enhancement)
273
+
274
+ ### Phase 4: Polish ✅ COMPLETE
275
+
276
+ - [x] Add `--check` flag for CI
277
+ - [x] Add idempotency tests
278
+ - [ ] Performance optimization (deferred - not needed currently)
279
+ - [ ] Editor integration docs (deferred)
280
+
281
+ ### Phase 5: Language Bindings (Future)
282
+
283
+ Expose formatter API to Python, TypeScript, and WASM for programmatic access.
284
+
285
+ **Use Cases:**
286
+
287
+ - VS Code extension format-on-save
288
+ - Jupyter notebook cell formatting
289
+ - Browser-based playground
290
+ - CI/CD pipeline integration without shelling out
291
+
292
+ #### [NEW] `domainforge-core/src/python/formatter.rs`
293
+
294
+ ```rust
295
+ use crate::formatter::{format, FormatConfig};
296
+ use pyo3::prelude::*;
297
+
298
+ #[pyfunction]
299
+ #[pyo3(signature = (source, indent_width=4, use_tabs=false))]
300
+ pub fn format_source(source: &str, indent_width: usize, use_tabs: bool) -> PyResult<String> {
301
+ let config = FormatConfig {
302
+ indent_width,
303
+ indent_style: if use_tabs { IndentStyle::Tabs } else { IndentStyle::Spaces },
304
+ ..Default::default()
305
+ };
306
+ format(source, config).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))
307
+ }
308
+ ```
309
+
310
+ **Python usage:**
311
+
312
+ ```python
313
+ from domainforge import format_source
314
+
315
+ formatted = format_source("""Entity "Foo" in bar""")
316
+ print(formatted) # Entity "Foo" in bar
317
+ ```
318
+
319
+ #### [NEW] `domainforge-core/src/typescript/formatter.rs`
320
+
321
+ ```rust
322
+ use crate::formatter::{format, FormatConfig};
323
+ use napi::bindgen_prelude::*;
324
+ use napi_derive::napi;
325
+
326
+ #[napi]
327
+ pub fn format_source(source: String, indent_width: Option<u32>, use_tabs: Option<bool>) -> napi::Result<String> {
328
+ let config = FormatConfig {
329
+ indent_width: indent_width.unwrap_or(4) as usize,
330
+ indent_style: if use_tabs.unwrap_or(false) { IndentStyle::Tabs } else { IndentStyle::Spaces },
331
+ ..Default::default()
332
+ };
333
+ format(&source, config).map_err(|e| napi::Error::from_reason(e.to_string()))
334
+ }
335
+ ```
336
+
337
+ **TypeScript usage:**
338
+
339
+ ```typescript
340
+ import { formatSource } from "@godspeedai/domainforge";
341
+
342
+ const formatted = formatSource(`Entity "Foo" in bar`);
343
+ console.log(formatted); // Entity "Foo" in bar
344
+ ```
345
+
346
+ #### [NEW] `domainforge-core/src/wasm/formatter.rs`
347
+
348
+ ```rust
349
+ use crate::formatter::{format, FormatConfig};
350
+ use wasm_bindgen::prelude::*;
351
+
352
+ #[wasm_bindgen]
353
+ pub fn format_source(source: &str, indent_width: Option<usize>, use_tabs: Option<bool>) -> Result<String, JsValue> {
354
+ let config = FormatConfig {
355
+ indent_width: indent_width.unwrap_or(4),
356
+ indent_style: if use_tabs.unwrap_or(false) { IndentStyle::Tabs } else { IndentStyle::Spaces },
357
+ ..Default::default()
358
+ };
359
+ format(source, config).map_err(|e| JsValue::from_str(&e.to_string()))
360
+ }
361
+ ```
362
+
363
+ **Browser usage:**
364
+
365
+ ```javascript
366
+ import { formatSource } from "@godspeedai/domainforge-wasm";
367
+
368
+ const formatted = formatSource(`Entity "Foo" in bar`);
369
+ document.getElementById("output").textContent = formatted;
370
+ ```
371
+
372
+ #### Phase 5 Tasks ✅ COMPLETE
373
+
374
+ - [x] Add `format_source` function to Python bindings
375
+ - [x] Add `formatSource` function to TypeScript bindings
376
+ - [x] Add `formatSource` function to WASM bindings
377
+ - [x] Add `check_format`/`checkFormat` helpers to all bindings
378
+ - [ ] Update binding documentation (python-api.md, typescript-api.md, wasm-api.md)
379
+ - [ ] Add cross-language formatter tests
380
+
381
+ ---
382
+
383
+ ## 7. Verification Plan
384
+
385
+ ### Unit Tests
386
+
387
+ Create `domainforge-core/tests/formatter_tests.rs`:
388
+
389
+ ```rust
390
+ #[test]
391
+ fn test_format_entity_basic() {
392
+ let input = "Entity \"Foo\" in bar";
393
+ let expected = "Entity \"Foo\" in bar\n";
394
+ assert_eq!(format(input), expected);
395
+ }
396
+
397
+ #[test]
398
+ fn test_format_preserves_comments() {
399
+ let input = "// Header\nEntity \"Foo\"";
400
+ let expected = "// Header\nEntity \"Foo\"\n";
401
+ assert_eq!(format(input), expected);
402
+ }
403
+
404
+ #[test]
405
+ fn test_format_idempotent() {
406
+ let input = include_str!("fixtures/payment.sea");
407
+ let once = format(input);
408
+ let twice = format(&once);
409
+ assert_eq!(once, twice);
410
+ }
411
+ ```
412
+
413
+ **Run tests:**
414
+
415
+ ```bash
416
+ cargo test -p domainforge-core formatter
417
+ ```
418
+
419
+ ### Integration Tests
420
+
421
+ Test against example files:
422
+
423
+ ```bash
424
+ # Format and verify output is valid
425
+ sea fmt examples/basic.sea > /tmp/formatted.sea
426
+ domainforge validate /tmp/formatted.sea
427
+
428
+ # Check mode for CI
429
+ sea fmt --check examples/basic.sea
430
+ ```
431
+
432
+ ### Binding Tests
433
+
434
+ ```python
435
+ # tests/test_formatter.py
436
+ def test_format_source():
437
+ from domainforge import format_source
438
+ result = format_source('Entity "Foo"')
439
+ assert result == 'Entity "Foo"\n'
440
+ ```
441
+
442
+ ```typescript
443
+ // typescript-tests/formatter.test.ts
444
+ import { formatSource } from "@godspeedai/domainforge";
445
+ import { expect, test } from "vitest";
446
+
447
+ test("formatSource normalizes whitespace", () => {
448
+ expect(formatSource('Entity "Foo"')).toBe('Entity "Foo"\n');
449
+ });
450
+ ```
451
+
452
+ ### Manual Verification
453
+
454
+ 1. Format a complex model file
455
+ 2. Compare before/after visually
456
+ 3. Verify semantics unchanged via:
457
+ ```bash
458
+ domainforge project --format calm before.sea > before.json
459
+ sea fmt before.sea --out after.sea
460
+ domainforge project --format calm after.sea > after.json
461
+ diff before.json after.json # Should be identical
462
+ ```
463
+
464
+ ---
465
+
466
+ ## 8. Risks and Mitigations
467
+
468
+ | Risk | Mitigation |
469
+ | ------------------------------- | -------------------------------------------------- |
470
+ | Comment preservation complexity | Start without comments in Phase 1, add in Phase 3 |
471
+ | Breaking existing workflows | Add `--check` mode for gradual adoption |
472
+ | Performance on large files | Benchmark, optimize only if needed |
473
+ | Grammar changes break parser | Extensive parser tests before modifying |
474
+ | Binding API divergence | Share core `format()` function across all bindings |
475
+
476
+ ---
477
+
478
+ ## 9. Open Questions
479
+
480
+ 1. **Should imports be auto-sorted?** (Proposed: Yes, alphabetically by path)
481
+ 2. **Should declaration order be enforced?** (Proposed: No, preserve user order)
482
+ 3. **Configuration file support?** (Proposed: Future - `.seafmt.toml`)
483
+ 4. **Should bindings support config objects?** (Proposed: Start with simple args, add config object later)
484
+
485
+ ---
486
+
487
+ ## 10. Related Documents
488
+
489
+ - [Grammar Spec](../reference/grammar-spec.md)
490
+ - [CLI Commands](../reference/cli-commands.md)
491
+ - [ADR-001: SEA-DSL as Semantic Source of Truth](../specs/ADR-001-sea-dsl-semantic-source-of-truth.md)
492
+ - [Python API](../reference/python-api.md)
493
+ - [TypeScript API](../reference/typescript-api.md)
494
+ - [WASM API](../reference/wasm-api.md)
495
+
496
+ ---
497
+
498
+ ## 11. Acceptance Criteria
499
+
500
+ ### Core (Phases 1-4) ✅
501
+
502
+ - [x] `sea fmt model.sea` outputs formatted code to stdout
503
+ - [x] `sea fmt model.sea --out formatted.sea` writes to file
504
+ - [x] `sea fmt --check model.sea` returns exit code 0 if already formatted, 1 otherwise
505
+ - [x] Formatting is idempotent (format twice = format once)
506
+ - [x] All 14 declaration types are supported
507
+ - [x] Comments are preserved (Phase 3)
508
+ - [x] Unit tests achieve >80% coverage of formatter module
509
+
510
+ ### Bindings (Phase 5) ✅
511
+
512
+ - [x] Python: `format_source()` function available in `domainforge` module
513
+ - [x] TypeScript: `formatSource()` function exported from `@godspeedai/domainforge`
514
+ - [x] WASM: `formatSource()` function available in browser bundle
515
+ - [x] All bindings produce identical output for same input (shared core)
516
+ - [ ] Cross-language formatter tests pass (deferred - requires E2E test infrastructure)
@@ -0,0 +1,18 @@
1
+ # Playbooks — DomainForge
2
+
3
+ Purpose: Operational step-by-step runbooks for maintainers, release engineers, and CI operators.
4
+
5
+ ## MECE checklist
6
+
7
+ - Step-by-step commands and preconditions
8
+ - Safety checks and rollback steps
9
+ - Triage and debugging steps
10
+ - Contacts and escalation path
11
+
12
+ ## Current Playbooks
13
+
14
+ - [Adding a New Primitive](adding-new-primitive.md)
15
+ - [Debugging Parser Failures](debugging-parser-failures.md)
16
+ - [Migrating Schema Versions](migrating-schema-versions.md)
17
+ - [Releasing Beta](releasing-beta.md)
18
+ - [Secret Management](secret-management.md)