behavior-contracts 0.1.3 → 0.2.1

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 (106) hide show
  1. package/README.md +8 -2
  2. package/dist/authoring.d.ts +202 -0
  3. package/dist/authoring.d.ts.map +1 -0
  4. package/dist/authoring.js +787 -0
  5. package/dist/authoring.js.map +1 -0
  6. package/dist/behavior.d.ts +248 -0
  7. package/dist/behavior.d.ts.map +1 -0
  8. package/dist/behavior.js +373 -0
  9. package/dist/behavior.js.map +1 -0
  10. package/dist/builder.d.ts +154 -0
  11. package/dist/builder.d.ts.map +1 -0
  12. package/dist/builder.js +574 -0
  13. package/dist/builder.js.map +1 -0
  14. package/dist/generator/core.d.ts +89 -0
  15. package/dist/generator/core.d.ts.map +1 -0
  16. package/dist/generator/core.js +124 -0
  17. package/dist/generator/core.js.map +1 -0
  18. package/dist/generator/emit-go.d.ts +19 -0
  19. package/dist/generator/emit-go.d.ts.map +1 -0
  20. package/dist/generator/emit-go.js +79 -0
  21. package/dist/generator/emit-go.js.map +1 -0
  22. package/dist/generator/emit-php.d.ts +20 -0
  23. package/dist/generator/emit-php.d.ts.map +1 -0
  24. package/dist/generator/emit-php.js +76 -0
  25. package/dist/generator/emit-php.js.map +1 -0
  26. package/dist/generator/emit-python.d.ts +10 -0
  27. package/dist/generator/emit-python.d.ts.map +1 -0
  28. package/dist/generator/emit-python.js +75 -0
  29. package/dist/generator/emit-python.js.map +1 -0
  30. package/dist/generator/emit-rust.d.ts +25 -0
  31. package/dist/generator/emit-rust.d.ts.map +1 -0
  32. package/dist/generator/emit-rust.js +125 -0
  33. package/dist/generator/emit-rust.js.map +1 -0
  34. package/dist/generator/emit-straightline-go.d.ts +77 -0
  35. package/dist/generator/emit-straightline-go.d.ts.map +1 -0
  36. package/dist/generator/emit-straightline-go.js +592 -0
  37. package/dist/generator/emit-straightline-go.js.map +1 -0
  38. package/dist/generator/emit-straightline-php.d.ts +46 -0
  39. package/dist/generator/emit-straightline-php.d.ts.map +1 -0
  40. package/dist/generator/emit-straightline-php.js +501 -0
  41. package/dist/generator/emit-straightline-php.js.map +1 -0
  42. package/dist/generator/emit-straightline-python.d.ts +36 -0
  43. package/dist/generator/emit-straightline-python.d.ts.map +1 -0
  44. package/dist/generator/emit-straightline-python.js +441 -0
  45. package/dist/generator/emit-straightline-python.js.map +1 -0
  46. package/dist/generator/emit-straightline-rust.d.ts +78 -0
  47. package/dist/generator/emit-straightline-rust.d.ts.map +1 -0
  48. package/dist/generator/emit-straightline-rust.js +615 -0
  49. package/dist/generator/emit-straightline-rust.js.map +1 -0
  50. package/dist/generator/emit-straightline-typed-go.d.ts +39 -0
  51. package/dist/generator/emit-straightline-typed-go.d.ts.map +1 -0
  52. package/dist/generator/emit-straightline-typed-go.js +828 -0
  53. package/dist/generator/emit-straightline-typed-go.js.map +1 -0
  54. package/dist/generator/emit-straightline-typed-rust.d.ts +48 -0
  55. package/dist/generator/emit-straightline-typed-rust.d.ts.map +1 -0
  56. package/dist/generator/emit-straightline-typed-rust.js +823 -0
  57. package/dist/generator/emit-straightline-typed-rust.js.map +1 -0
  58. package/dist/generator/emit-straightline-typed-typescript.d.ts +49 -0
  59. package/dist/generator/emit-straightline-typed-typescript.d.ts.map +1 -0
  60. package/dist/generator/emit-straightline-typed-typescript.js +314 -0
  61. package/dist/generator/emit-straightline-typed-typescript.js.map +1 -0
  62. package/dist/generator/emit-straightline-typescript.d.ts +36 -0
  63. package/dist/generator/emit-straightline-typescript.d.ts.map +1 -0
  64. package/dist/generator/emit-straightline-typescript.js +397 -0
  65. package/dist/generator/emit-straightline-typescript.js.map +1 -0
  66. package/dist/generator/emit-typescript.d.ts +11 -0
  67. package/dist/generator/emit-typescript.d.ts.map +1 -0
  68. package/dist/generator/emit-typescript.js +68 -0
  69. package/dist/generator/emit-typescript.js.map +1 -0
  70. package/dist/generator/fingerprint.d.ts +14 -0
  71. package/dist/generator/fingerprint.d.ts.map +1 -0
  72. package/dist/generator/fingerprint.js +74 -0
  73. package/dist/generator/fingerprint.js.map +1 -0
  74. package/dist/generator/index.d.ts +22 -0
  75. package/dist/generator/index.d.ts.map +1 -0
  76. package/dist/generator/index.js +64 -0
  77. package/dist/generator/index.js.map +1 -0
  78. package/dist/generator/literal.d.ts +15 -0
  79. package/dist/generator/literal.d.ts.map +1 -0
  80. package/dist/generator/literal.js +232 -0
  81. package/dist/generator/literal.js.map +1 -0
  82. package/dist/generator/straightline.d.ts +147 -0
  83. package/dist/generator/straightline.d.ts.map +1 -0
  84. package/dist/generator/straightline.js +122 -0
  85. package/dist/generator/straightline.js.map +1 -0
  86. package/dist/generator/typed.d.ts +156 -0
  87. package/dist/generator/typed.d.ts.map +1 -0
  88. package/dist/generator/typed.js +108 -0
  89. package/dist/generator/typed.js.map +1 -0
  90. package/dist/guard.d.ts +36 -0
  91. package/dist/guard.d.ts.map +1 -1
  92. package/dist/guard.js +186 -0
  93. package/dist/guard.js.map +1 -1
  94. package/dist/index.d.ts +17 -3
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +23 -2
  97. package/dist/index.js.map +1 -1
  98. package/dist/plan.d.ts +36 -0
  99. package/dist/plan.d.ts.map +1 -1
  100. package/dist/plan.js +152 -14
  101. package/dist/plan.js.map +1 -1
  102. package/dist/primitives.d.ts +112 -0
  103. package/dist/primitives.d.ts.map +1 -0
  104. package/dist/primitives.js +206 -0
  105. package/dist/primitives.js.map +1 -0
  106. package/package.json +4 -1
@@ -0,0 +1,125 @@
1
+ import { emitDocLiteral } from "./literal.js";
2
+ function rustStrLit(s) {
3
+ // 識別子・fingerprint 用(ASCII 前提だが JSON エスケープで安全側に倒す)。
4
+ return JSON.stringify(s);
5
+ }
6
+ /** rustfmt の fits-on-one-line 規則を模倣した COMPONENT_NAMES 配列 emit。 */
7
+ function componentNamesConst(names) {
8
+ const items = names.map(rustStrLit);
9
+ const oneLine = `pub const COMPONENT_NAMES: [&str; ${names.length}] = [${items.join(", ")}];`;
10
+ if (oneLine.length <= 100)
11
+ return oneLine;
12
+ return `pub const COMPONENT_NAMES: [&str; ${names.length}] = [\n${items.map((s) => ` ${s},`).join("\n")}\n];`;
13
+ }
14
+ function emit(ctx) {
15
+ const { fingerprint, specVersions, componentNames, runtimeImport } = ctx;
16
+ const irLiteral = emitDocLiteral(ctx.ir, "rust", 1);
17
+ return `// GENERATED by behavior-contracts common generator (bc#13) — DO NOT EDIT.
18
+ // Input: portable component-graph IR only (scp-ir-architecture.md §5/§7.4).
19
+ // This module is the codegen endpoint (§7.3 endpoint 3): the IR is embedded as
20
+ // NATIVE json! constructor code (compile-time checked; no JSON-text parsing at
21
+ // runtime) and handed to the EXISTING runtime core (run_behavior) — no execution
22
+ // logic is generated. Handlers are ALWAYS injected at the boundary
23
+ // (IR + {effects,config,hooks} — concept.md §4.4); they are never generated.
24
+ //
25
+ // Const deviation (documented): serde_json::Value is not const-constructible, so
26
+ // the IR is built ONCE on first use behind std::sync::LazyLock (requires Rust
27
+ // >= 1.80). The first-use fail-closed checks (#208 prepared-artifact discipline)
28
+ // run inside the initializer: a spec-version skew or fingerprint mismatch panics
29
+ // LOUDLY before any behavior can run.
30
+ // irFingerprint: ${fingerprint}
31
+
32
+ use ${runtimeImport}::{
33
+ fingerprint_component_graph, run_behavior, BehaviorError, ComponentExec, SpecVersions, Value,
34
+ };
35
+ use serde_json::{json, Value as J};
36
+ use std::sync::LazyLock;
37
+
38
+ /// Spec versions baked at generation time (fail-closed comparison on first use).
39
+ pub const EXPECTED_SPEC_VERSIONS: [(&str, i64); 3] =
40
+ [("behavior", ${specVersions.behavior}), ("expression", ${specVersions.expression}), ("plan", ${specVersions.plan})];
41
+
42
+ /// FNV-1a 64 fingerprint of the source portable IR (canonical_json discipline, #208).
43
+ pub const IR_FINGERPRINT: &str = ${rustStrLit(fingerprint)};
44
+
45
+ /// Component names exposed by bind(), in IR declaration order.
46
+ ${componentNamesConst(componentNames)}
47
+
48
+ /// The portable component-graph IR, built once on first use from native json!
49
+ /// constructor code (no JSON-text parsing at runtime; see the const-deviation
50
+ /// note in the module header).
51
+ pub static IR: LazyLock<J> = LazyLock::new(|| {
52
+ let ir = json!(${irLiteral});
53
+ check_generated_module(&ir);
54
+ ir
55
+ });
56
+
57
+ fn runtime_spec_version(key: &str) -> i64 {
58
+ match key {
59
+ "behavior" => SpecVersions::BEHAVIOR,
60
+ "expression" => SpecVersions::EXPRESSION,
61
+ "plan" => SpecVersions::PLAN,
62
+ other => {
63
+ panic!("behavior-contracts generated module: unknown spec key '{other}' (fail-closed)")
64
+ }
65
+ }
66
+ }
67
+
68
+ // First-use fail-closed checks (#208 prepared-artifact discipline).
69
+ fn check_generated_module(ir: &J) {
70
+ for (key, want) in EXPECTED_SPEC_VERSIONS {
71
+ let got = runtime_spec_version(key);
72
+ if got != want {
73
+ panic!("behavior-contracts generated module: spec-version skew for '{key}' (generated={want}, runtime={got}) — regenerate against this runtime (fail-closed)");
74
+ }
75
+ }
76
+ for name in COMPONENT_NAMES {
77
+ let found = ir["components"]
78
+ .as_array()
79
+ .is_some_and(|cs| cs.iter().any(|c| c["name"] == name));
80
+ if !found {
81
+ panic!("behavior-contracts generated module: component '{name}' missing from the embedded IR — the generated code was modified or corrupted (fail-closed)");
82
+ }
83
+ }
84
+ let got_fp = fingerprint_component_graph(ir).unwrap_or_else(|e| {
85
+ panic!(
86
+ "behavior-contracts generated module: fingerprint recompute failed: {e} (fail-closed)"
87
+ )
88
+ });
89
+ if got_fp != IR_FINGERPRINT {
90
+ panic!("behavior-contracts generated module: IR fingerprint mismatch (baked={IR_FINGERPRINT}, embedded literal={got_fp}) — the generated code was modified or corrupted (fail-closed)");
91
+ }
92
+ }
93
+
94
+ /// Injected-handler accessor over the embedded IR (see [\`bind\`]). Rust ownership
95
+ /// makes a map of per-component closures sharing one \`&mut handlers\` impractical,
96
+ /// so the per-component executor surface is \`call(name, input)\` with the
97
+ /// component name checked against [\`COMPONENT_NAMES\`] by the runtime core.
98
+ pub struct Bound<H: ComponentExec> {
99
+ handlers: H,
100
+ }
101
+
102
+ /// bind — inject handlers (boundary injection; catalog name → implementation)
103
+ /// and get an executor over the embedded IR. Each \`call\` delegates to the
104
+ /// runtime core's run_behavior (dynamic-path equivalent — §7.3). Forces the
105
+ /// first-use fail-closed checks.
106
+ pub fn bind<H: ComponentExec>(handlers: H) -> Bound<H> {
107
+ LazyLock::force(&IR);
108
+ Bound { handlers }
109
+ }
110
+
111
+ impl<H: ComponentExec> Bound<H> {
112
+ pub fn call(&mut self, name: &str, input: &[(String, Value)]) -> Result<Value, BehaviorError> {
113
+ run_behavior(&IR, &mut self.handlers, input, Some(name))
114
+ }
115
+ }
116
+ `;
117
+ }
118
+ export const rustEmitter = {
119
+ language: "rust",
120
+ fileExtension: ".rs",
121
+ defaultRuntimeImport: "behavior_contracts",
122
+ filenameHint: "behaviors_generated.rs",
123
+ emit,
124
+ };
125
+ //# sourceMappingURL=emit-rust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-rust.js","sourceRoot":"","sources":["../../src/generator/emit-rust.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,SAAS,UAAU,CAAC,CAAS;IAC3B,mDAAmD;IACnD,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED,kEAAkE;AAClE,SAAS,mBAAmB,CAAC,KAAe;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,qCAAqC,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9F,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,qCAAqC,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AACnH,CAAC;AAED,SAAS,IAAI,CAAC,GAAgB;IAC5B,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC;IACzE,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO;;;;;;;;;;;;;oBAaW,WAAW;;MAEzB,aAAa;;;;;;;;oBAQC,YAAY,CAAC,QAAQ,qBAAqB,YAAY,CAAC,UAAU,eAAe,YAAY,CAAC,IAAI;;;mCAGlF,UAAU,CAAC,WAAW,CAAC;;;EAGxD,mBAAmB,CAAC,cAAc,CAAC;;;;;;qBAMhB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgE7B,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAkB;IACxC,QAAQ,EAAE,MAAM;IAChB,aAAa,EAAE,KAAK;IACpB,oBAAoB,EAAE,oBAAoB;IAC1C,YAAY,EAAE,wBAAwB;IACtC,IAAI;CACL,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * emit-straightline-go.ts — Go 直線 emitter(bc#38 / Layer A2, de-interpretation)。
3
+ *
4
+ * typed-codegen.md §4.1 の Go 具体化。language-neutral な {@link StraightlineDialect} を
5
+ * 実装し、component ごとに「plan を A0 の `RunPlan` primitive で直呼び・各ノードの port 評価と
6
+ * handler 呼びを直線展開した」ネイティブ **Go** 関数を emit する。生成コードは
7
+ * **`RunBehavior` の tree-walk(nodeKind ディスパッチ / evalPorts / 汎用 output 評価)を
8
+ * 経由しない**(A1 と同じ骨組み)。
9
+ *
10
+ * 式の綴じ方(A2 の眼目 = Phase B の脱解釈利得 — TS oracle と決定的に異なる点):
11
+ * - **単純式はネイティブ化する(AC#2)**:
12
+ * - `ref` / `refOpt` → 生成モジュール内の native Go helper(`slRef` / `slRefOpt`)で
13
+ * `*Obj.Get` を直接歩く scope/field アクセス。`EvaluateExpression` も `Prim*` も呼ばない。
14
+ * - `concat` → native Go `strings.Builder` 連結(`slConcat`。part は再帰的に native emit)。
15
+ * これで単純 port の式ツリー `evaluate()` 解釈が生成コードから**消える**。native helper は
16
+ * expr.go の意味論(`UNKNOWN_BINDING` / `NULL_REF` / `MISSING_PROP` / `TYPE_MISMATCH` /
17
+ * `refOpt` の null 伝播 / concat の「string 以外は TYPE_MISMATCH」/ arity>=2)を
18
+ * **同じ Failure code で**再現する(意味論の等価は conformance で pin)。
19
+ * - **overflow / 短絡系はネイティブ化しない**: `add`/`sub`/`mul`/`neg`/`div`/`mod` は
20
+ * INT_OVERFLOW / PRECISION_LOSS / MOD_ZERO 等の fail-closed 意味論、`and`/`or`/`cond`/
21
+ * `coalesce` は短絡(未評価 IR を渡して primitive 内 evaluate が短絡)を保存するため、
22
+ * A0 primitive SSoT(`Prim*`)を直呼びする(再実装しない)。`eq`/`ne`/比較/`obj`/`arr`/
23
+ * `len`/`int`/`float` も SSoT を呼ぶ(型判定・code-point 順・checked リテラルの一本化)。
24
+ * - 上記いずれにも当たらないむき出しスカラ(cond then/else の bare リテラル等)は `EvalExpr`
25
+ * (同一 SSoT)へ落とす(型判定を生成コードに残さない)。
26
+ *
27
+ * この emitter は A1 の TS golden oracle と観測等価(値・発行 op 列・Failure)であることを
28
+ * conformance(codegen-straightline.test.ts の Go 節)で実 Go toolchain 実行により pin する。
29
+ */
30
+ import type { EmitterPlugin } from "./core.js";
31
+ import { type ComponentPlan, type StraightlineDialect } from "./straightline.js";
32
+ /**
33
+ * emitExpr — Expression IR ノードを「scope を受けて (Value, error) を返す」Go 式に落とす。
34
+ *
35
+ * 単純式は **native Go helper** へ(脱解釈 — AC#2)、overflow/短絡系は A0 primitive SSoT へ、
36
+ * むき出しスカラは EvalExpr(同一 SSoT)へ落とす。生成される Go 式はどれも `(Value, error)` を
37
+ * 返すので、直線関数側は `must(<expr>)` で 1 行に畳んで scope へ束ねる。
38
+ * - `{ref:[...]}` → `${PKG}.slRef(<path>, scope)` (native scope/field walk)
39
+ * - `{refOpt:[...]}` → `${PKG}? no — slRefOpt` (native, null 伝播)
40
+ * - `{concat:[...]}` → `slConcat([]slPart{...}, scope)` (native strings.Builder)
41
+ * - overflow/短絡 → `${PKG}.PrimAdd(...)` 等 (SSoT 直呼び)
42
+ * - bare scalar → `${PKG}.EvalExpr(<lit>, scope)` (SSoT)
43
+ * slRef/slRefOpt/slConcat は **生成モジュール内の native helper**(`EvaluateExpression`/`Prim*`
44
+ * を呼ばない)で、pure ref/concat の生成コードには evaluate/primitive 呼びが一切現れない
45
+ * (AC#2 の構造的 grep 証明)。
46
+ */
47
+ declare function emitExpr(node: unknown, scopeVar: string): string;
48
+ /** ops リテラル(RunPlan に渡す []OpSpec の Go リテラル)を綴じる。 */
49
+ declare function emitOpsLiteral(plan: ComponentPlan): string;
50
+ /** port ローカル変数名(Go 識別子として安全・一意)。宣言順に p0,p1,… を index で衝突回避。 */
51
+ declare function goPortVar(name: string): string;
52
+ /** behavior plan({groups, concurrency})を *ExecutionPlanSpec Go リテラルへ。 */
53
+ declare function emitBehaviorPlanLiteral(plan: unknown): string;
54
+ /** component 名を Go 関数名に使える形へ(決定的。名前一意は DUPLICATE_COMPONENT で保証)。 */
55
+ declare function sanitize(name: string): string;
56
+ /**
57
+ * go-typed(bc#47)が struct-native exec を綴じるために再利用する内部 emit ヘルパ。straight-line の
58
+ * plan/handler-dispatch SSoT(RunPlan + ExecHandler + native/primitive port eval)をそのまま使い、
59
+ * 「結果を Value scope でなく struct scope に持つ」差分だけを typed 側で足すための seam。runtime 語彙
60
+ * (PKG)と ops/plan リテラル・式 emit を共有する(意味論の二重実装を避ける)。
61
+ */
62
+ export declare const goStraightlineInternals: {
63
+ PKG: string;
64
+ emitExpr: typeof emitExpr;
65
+ emitOpsLiteral: typeof emitOpsLiteral;
66
+ emitBehaviorPlanLiteral: typeof emitBehaviorPlanLiteral;
67
+ goPortVar: typeof goPortVar;
68
+ sanitize: typeof sanitize;
69
+ dialect: StraightlineDialect;
70
+ };
71
+ /**
72
+ * goStraightlineEmitter — 言語識別子 `"go-straightline"` の emitter plugin。
73
+ * 既存の `go`(リテラル焼き込み・endpoint 3-literal)と併存する additive な第2モード。
74
+ */
75
+ export declare const goStraightlineEmitter: EmitterPlugin;
76
+ export {};
77
+ //# sourceMappingURL=emit-straightline-go.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-straightline-go.d.ts","sourceRoot":"","sources":["../../src/generator/emit-straightline-go.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,WAAW,CAAC;AAE5D,OAAO,EAEL,KAAK,aAAa,EAElB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAyD3B;;;;;;;;;;;;;;GAcG;AACH,iBAAS,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA6BzD;AA2BD,oDAAoD;AACpD,iBAAS,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CASnD;AAqCD,+DAA+D;AAC/D,iBAAS,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvC;AAqND,yEAAyE;AACzE,iBAAS,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAMtD;AAED,oEAAoE;AACpE,iBAAS,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtC;AAkLD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;CAQnC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAMnC,CAAC"}