@skillstech/thunderlang 0.1.6

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 (72) hide show
  1. package/CHANGELOG.md +375 -0
  2. package/LICENSE +21 -0
  3. package/README.md +165 -0
  4. package/dist/core.cjs +6768 -0
  5. package/dist/index.cjs +9308 -0
  6. package/intent-graph.schema.json +687 -0
  7. package/package.json +84 -0
  8. package/src/ai-core.mjs +67 -0
  9. package/src/ai-events.mjs +56 -0
  10. package/src/ai.mjs +324 -0
  11. package/src/arch.mjs +55 -0
  12. package/src/atlas.mjs +118 -0
  13. package/src/changes.mjs +74 -0
  14. package/src/classification.mjs +36 -0
  15. package/src/cli.mjs +1534 -0
  16. package/src/codegen.mjs +214 -0
  17. package/src/compile.mjs +142 -0
  18. package/src/comprehension.mjs +130 -0
  19. package/src/conflict.mjs +0 -0
  20. package/src/core.d.ts +99 -0
  21. package/src/core.mjs +92 -0
  22. package/src/data-schema.mjs +137 -0
  23. package/src/decision.mjs +38 -0
  24. package/src/distributed.mjs +48 -0
  25. package/src/draft.mjs +101 -0
  26. package/src/drift.mjs +177 -0
  27. package/src/emit.mjs +519 -0
  28. package/src/exporters.mjs +245 -0
  29. package/src/expr.mjs +245 -0
  30. package/src/fable.mjs +110 -0
  31. package/src/focus.mjs +151 -0
  32. package/src/format.mjs +55 -0
  33. package/src/governance.mjs +100 -0
  34. package/src/graph-source.mjs +292 -0
  35. package/src/guard.mjs +105 -0
  36. package/src/guardian.mjs +98 -0
  37. package/src/hash.mjs +89 -0
  38. package/src/importers.mjs +194 -0
  39. package/src/index.d.ts +725 -0
  40. package/src/index.mjs +185 -0
  41. package/src/intellisense.mjs +210 -0
  42. package/src/intent-atlas.mjs +77 -0
  43. package/src/intent-graph.mjs +346 -0
  44. package/src/intent-ir.mjs +144 -0
  45. package/src/intent-schema.mjs +215 -0
  46. package/src/ledger.mjs +109 -0
  47. package/src/lifecycle.mjs +56 -0
  48. package/src/lift.mjs +693 -0
  49. package/src/lsp.mjs +152 -0
  50. package/src/mcp.mjs +158 -0
  51. package/src/migrate.mjs +118 -0
  52. package/src/outcome.mjs +93 -0
  53. package/src/parse.mjs +733 -0
  54. package/src/patch.mjs +364 -0
  55. package/src/privacy.mjs +61 -0
  56. package/src/proof-schema.mjs +129 -0
  57. package/src/report.mjs +84 -0
  58. package/src/runtime.mjs +96 -0
  59. package/src/sarif.mjs +88 -0
  60. package/src/scan-queries.mjs +97 -0
  61. package/src/scan.mjs +87 -0
  62. package/src/security.mjs +73 -0
  63. package/src/select.mjs +80 -0
  64. package/src/semantic-diff.mjs +125 -0
  65. package/src/simulate.mjs +106 -0
  66. package/src/style.mjs +250 -0
  67. package/src/sync.mjs +103 -0
  68. package/src/testing.mjs +59 -0
  69. package/src/twelve-factor.mjs +173 -0
  70. package/src/verify-diff.mjs +105 -0
  71. package/src/xml.mjs +87 -0
  72. package/syntaxes/intent.tmLanguage.json +55 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,375 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@skillstech/thunderlang`. Pre-1.0: the language and the
4
+ `intent-graph-v1` schema version independently and may still change.
5
+
6
+ ## 0.1.6
7
+
8
+ The agent-conformance release (skills on intents + 12-factor scoring). Additive; no breaking
9
+ changes to 0.1.5.
10
+
11
+ ### Added
12
+
13
+ - **12-Factor Agents conformance lens (`twelve-factor-v1`).** Deterministically scores an intent
14
+ against the 13 principles of [humanlayer/12-factor-agents](https://github.com/humanlayer/12-factor-agents),
15
+ which map onto structure IL already models (decisions, lifecycles, typed I/O, approvals,
16
+ errors/handlers, events, a pure runtime). `twelveFactorReport(ast)` returns a per-factor verdict
17
+ (`satisfied` | `partial` | `absent`) with evidence + a fix and a 0–100 score; `twelveFactorSummary`
18
+ is the compact form. `compileSource` and the proof envelope now carry a `twelveFactor` summary, so
19
+ "12-factor compliant" is a claim the proof asserts. CLI: `intent twelve-factor <file> [--json]`.
20
+ Findings catalogued as `IL-12F-01..13`. Exported from `/core` and the root. See
21
+ `docs/twelve-factor-agents.md` and `examples/TwelveFactorAgent.intent` (scores 100/100).
22
+
23
+ - **Skills + required-understanding on intents (the Ownership Graph skill↔intent join).** A mission
24
+ can declare the skills it requires and what a human must be able to explain to own it:
25
+ ```
26
+ requires_skill Distributed Systems, Idempotency
27
+ demonstrates understands the idempotency-key guarantee
28
+ ```
29
+ - `requires_skill` (inline comma list or a block) normalizes each skill to the shared
30
+ `skill:<slug>` id (`skillRefId`); `demonstrates` captures the understanding a human must show.
31
+ - New `Skill` node type (`NODE_TYPES` 41 → 42) + `requires_skill` relationship (20 → 21) in
32
+ `intent-graph-v1`; the mission `requires_skill` each Skill node. Additive for consumers that
33
+ subset the vocabulary.
34
+ - The proof envelope and `compileSource` now carry `skillsRequired` (the `skill:` ids) and
35
+ `demonstrates` (prose), so producers drop `skillsRequired` straight into
36
+ `evidence-event-v1` `skillIds[]`, and `demonstrates` feeds Skills Tech Talk defense.
37
+ - `requires_skill` round-trips through `graphToSource`.
38
+
39
+ ## 0.1.5
40
+
41
+ The rule-catalog namespace release. Additive; no breaking changes to 0.1.4.
42
+
43
+ ### Added
44
+
45
+ - **Verify-time rule namespace.** The canonical rule catalog is now one id space across two phases:
46
+ author-time (ThunderLang) and verify-time (OpenThunder). Every rule row self-describes `owner`
47
+ (`IL` | `OT`) and `phase` (`author` | `verify`); `RULE_NAMESPACES` declares prefix ownership
48
+ (`IL-*` author, `OT-*` verify); `VERIFICATION_RULES` reserves the OpenThunder verify namespace
49
+ (`OT-REQ-*`, `reserved: true` until OT defines them); `ruleNamespace(ruleId)` resolves owner+phase
50
+ for any id. `ALL_DIAGNOSTICS` now spans both phases. Existing consumers keying on `ruleId` are
51
+ unaffected (owner/phase are additive fields). Exported from `/core` and the root.
52
+
53
+ ## 0.1.4
54
+
55
+ The shared-skill-namespace release. Additive; no breaking changes to 0.1.3.
56
+
57
+ ### Added
58
+
59
+ - **Canonical skill id (`skillRefId`).** IL owns the `skill:` id namespace (founder decision
60
+ 2026-07-14); SkillsTech Certified owns the curated content (which skills exist, cert->skill maps).
61
+ `skillRefId('TypeScript') -> 'skill:typescript'` , deterministic, browser-safe, so every product
62
+ emits the SAME skill id in Workspace `evidence-event-v1` `skillIds[]`. The id primitive only; the
63
+ curated taxonomy list lands separately (STCE, post-loop). Exported from `/core` and the root.
64
+
65
+ ### Fixed
66
+
67
+ - **`compileSource` type now includes `origin`.** The `.d.ts` opts omitted `origin?: string` even
68
+ though the runtime has honored it since 0.1.1 (OpenThunder confirmed `origin: 'recovered'`
69
+ round-trips). Typed consumers can now pass it without a cast. Runtime behavior unchanged.
70
+
71
+ ## 0.1.3
72
+
73
+ The Ownership-Loop seam release. Additive; no breaking changes to 0.1.2.
74
+
75
+ ### Added
76
+
77
+ - **Canonical intent reference id (`intentRefId`).** The stable string every SkillsTech product
78
+ puts in Workspace `evidence-event-v1` / `proof-bundle-v1` `intentReferences[]` so an evidence
79
+ record or Ownership Proof cites the exact intent it supports:
80
+ `intent:<mission-slug>` (subject-level) and `intent:<mission-slug>@<sha8>` (version-pinned to the
81
+ proof `sourceHash`). Deterministic, browser-safe, exported from `/core` and the root.
82
+ - **`compileSource` returns `intentRef` + `intentRefPinned`,** so a producer that already compiled
83
+ a mission gets both ids for free (no need to recompute). This closes the `ThunderLang -> evidence
84
+ model` seam of the Skills Ownership Loop.
85
+
86
+ ## 0.1.2
87
+
88
+ The ecosystem-consumption release. Additive; no breaking changes to 0.1.1.
89
+
90
+ ### Added
91
+
92
+ - **Dual CommonJS + ESM build.** The package now ships a `require`-able CommonJS build
93
+ (`dist/index.cjs`, `dist/core.cjs`) alongside the ESM sources, via conditional exports.
94
+ CommonJS consumers (OpenThunder, the SkillsTech backend) can now
95
+ `const { NODE_TYPES } = require('@skillstech/thunderlang/core')` synchronously , no async
96
+ bootstrap, no ESM migration. The runtime stays zero-dependency (esbuild is dev-only).
97
+ - **Seeded lift.** `liftSource(source, { seeds })` accepts OpenThunder's `intent-ir-v1` nodes
98
+ (`IntentSeed`: `nodeId` + `evidenceRef` with `signals`, `sourceLocations`, optional
99
+ `ledgerRef` , see `SEED_SCHEMA`). The lifted draft then references OT's exact node ids in
100
+ `maps_to` (no divergent second reading of the repo) and returns the linkage structurally via
101
+ `result.seeds` / `summary.seeds`. Additive: with no `seeds`, output is byte-identical to 0.1.1.
102
+ Exports `SEED_SCHEMA` and `normalizeSeeds` from `/core` and the root.
103
+
104
+ ## 0.1.1
105
+
106
+ The executable + interoperable release. Everything is deterministic and requires no AI.
107
+
108
+ ### Added
109
+
110
+ - **Executable intent (the Intent Runtime).** `evaluateDecision` (FIRST-hit, full trace),
111
+ `simulateLifecycle` (walk a state machine, reject illegal transitions), and
112
+ `checkDecisionCases`, powered by a safe no-`eval` expression engine. CLI: `intent run`,
113
+ `intent simulate`.
114
+ - **First-class tests.** `test` blocks (`case` / `scenario`) inside a `.intent` file, run
115
+ with `intent test` and `runTests`. The spec proves itself.
116
+ - **Outcome contracts.** `outcome_contract` binds an outcome to a target; `evaluateOutcomes`
117
+ and `intent outcomes` judge it met / missed / pending against a delivery `result`.
118
+ - **Full five-profile language.** System (`capability`, `interface`), delivery (`release`,
119
+ `result`, `learning`), and design (`component`, `artifact`) profiles join core, product,
120
+ and experience. Governance (`waiver`) and data privacy (`data`) too.
121
+ - **Interop.** Export to DMN, BPMN, NuSMV, JSON Schema, OpenAPI, W3C Design Tokens, and
122
+ Mermaid , the whole Intent Graph as a paste-anywhere diagram , (`intent export`, `toMermaid`);
123
+ import from DMN and BPMN with a fidelity report (`intent import`, `importReport`); native
124
+ graph <-> source round-trip (`graphToSource`, `intent source`); schema migrations
125
+ (`migrateGraph`, `validateGraph`, `intent migrate` / `validate`); semantic diff + 3-way
126
+ merge (`intent diff` / `merge`).
127
+ - **Editor support.** A Language Server (`intent lsp`, `startLspServer`) providing
128
+ diagnostics, completion, and hover over LSP; a TextMate grammar
129
+ (`syntaxes/intent.tmLanguage.json`) for syntax highlighting.
130
+ - **Onboarding + CI.** `intent init` scaffolds a runnable starter; `intent check <dir>`
131
+ recurses and gates a whole repo; `intent check --json` and `intent explain <CODE>` for
132
+ tooling; a composite GitHub Action.
133
+ - **Style intent.** `style_intent` models brand + visual language as a governed
134
+ Experience-profile extension: design tokens bind to a canonical, lockable address space,
135
+ and `accessibility_target` is always a `proposed` claim (never IL-verified). `analyzeStyle`,
136
+ `styleDiagnostics`, `intent style`, diagnostics `IL-STYLE-001..005`, canonical `StyleIntent`
137
+ node with graph round-trip. Browser-safe via `/core`. Exports to **W3C Design Tokens
138
+ (DTCG)** via `intent export --format tokens` / `toDesignTokens` (`intent-design-tokens-v1`)
139
+ and to a ready-to-use **CSS** custom-property sheet via `--format css` / `toCss`. Experiences
140
+ export to a **Playwright** E2E test scaffold via `--format playwright` / `toPlaywright`.
141
+ - **Security + type diagnostics.** Deterministic checks for the mistakes prompts ship:
142
+ `IL-SEC-001` (secret-typed field on an event payload), `IL-SEC-002` (API returns a secret
143
+ with no auth requirement), `IL-TYPE-001` (unrecognized, likely-mistyped field type).
144
+ `securityDiagnostics`, `isRecognizedType`, catalog now 49 rules.
145
+ - **Human <-> Structured <-> ThunderLang sync (`intent-sync-v1`).** `parseToStructured(source)`
146
+ returns the canonical graph + flat PM fields; `proposeIntent(structured, { base })` regenerates
147
+ ThunderLang source with a reviewable diff, surfaced ambiguities (non-factual nodes), round-trip
148
+ fidelity gaps, and validation , never a silent rewrite. Browser-safe via `/core` (for Studio).
149
+ - **Comment-preserving structural editing (`intent-patch-v1`).** `applyEdits(source, edits)`
150
+ applies field-level edits (`setField`, `add/removeGuarantee`, `add/removeNever`,
151
+ `add/removeField`, `setFieldType` on inputs/outputs, `add/removeMetric`, `setMetricField`,
152
+ `add/removeOutcome`, and decision rules `add/removeRule`/`setRule`/`setDefault`) directly to
153
+ the `.intent` source, touching
154
+ only the target lines so comments, formatting, and untouched blocks stay byte-identical. Closes
155
+ the sync fidelity gap: a PM edits fields and IL keeps the comments. Field removal takes the
156
+ field's indented modifiers with it (no orphans). Unmatched/unsupported edits are reported,
157
+ never applied blindly. Browser-safe. Also a CLI: `intent edit <file> --edits <json|-> |
158
+ --set-goal | --add-guarantee | ... [--write]`.
159
+ - **Verify a code change against its intent (`intent-verify-diff-v1`).** `intent verify-diff
160
+ <intent> --after <code> [--before <code>]` / `verifyDiff()` proves, deterministically and with
161
+ no AI, which of the intent's guarantees/never-rules a change upholds or breaks, and returns a
162
+ gate verdict (PASS/BLOCK, non-zero exit on BLOCK). Blocks on regressions (a claim that held
163
+ before and broke after) and guardrail hits (an added line pushing a never-rule's protected
164
+ secret into a log/response). The keystone of the AI generate-verify loop; honest (catches
165
+ mechanical violations, does not claim to prove correctness).
166
+ - **Intent Atlas + lift-all.** `liftAll(source)` / `intent lift <file> --all` lifts EVERY public
167
+ function in a file into its own inferred mission (not just the first), filtering internal
168
+ helpers (Go: exported-only; Python/Ruby: top-level, non-underscore) , so a whole module reads
169
+ as intent. Powers the Intent Atlas: `scripts/build-atlas.mjs` lifts well-known OSS projects
170
+ (Requests, Express, Flask, gorilla/mux, chi) into a browsable /atlas of ~99 inferred missions.
171
+ - **Prompt -> intent (`intent-draft-v1`).** `draftIntent(brief)` / `intent draft --brief <json|->`
172
+ turns a structured brief into a rigorous, canonically-formatted intent draft PLUS a review
173
+ checklist of what a human must still fill in (unverified guarantee, decision with no default,
174
+ unguarded secret, missing goal). The deterministic half of prompt->intent , an agent produces
175
+ the brief (MCP tool `intent_draft`), IL makes it rigorous, a human approves. Never verified.
176
+ Browser-safe.
177
+ - **Runtime enforcement (`intent-guard-v1`).** `compileGuard(intentSource)` / `buildGuard(ast)`
178
+ turns intent into a guard that runs IN the application: `redact(obj)` masks every field the
179
+ intent declares secret (Secret/Password/Token type, pii/sensitive data, or a secret-looking
180
+ name), deeply , so wrapping a logger enforces "never expose the token"; `assertAllowed(name,
181
+ inputs)` runs a declared decision and THROWS `INTENT_GUARD_DENIED` when the intent denies the
182
+ action , the intent's rules become a hard production gate. `intent guard <file>` previews it.
183
+ Browser-safe.
184
+ - **MCP server for AI agents.** `intent mcp` / `startMcpServer` speaks the Model Context
185
+ Protocol over stdio, exposing ThunderLang as native tools for coding agents (Claude Code,
186
+ Cursor, ...): `intent_verify_diff` (the gate), `intent_check`, `intent_lift`, `intent_run`,
187
+ `intent_test`, `intent_graph`, `intent_explain`. The agent checks its own output against the
188
+ intent before shipping.
189
+ - **Hardening: two runtime correctness bugs fixed + a focus performance fix.**
190
+ - *Divide/modulo by zero* leaked `Infinity`/`NaN` into comparisons, so a decision rule like
191
+ `when balance / count > threshold` would silently MATCH when `count == 0` (`Infinity > 1`
192
+ is true). Non-finite arithmetic is now neutralized to `null`.
193
+ - *Unknown-operand ordering* was inconsistent: `null < 1` was `true` (JS coerces `null` to 0)
194
+ while `null > 1` was `false`. Every ordering comparison against an unknown / neutralized
195
+ value (a missing input, a divide-by-zero) is now `false` , unknowns are un-orderable.
196
+ - *Lifecycle initial state* was picked as "the first state with no inbound transition," which
197
+ is wrong when the start state is in a cycle (`A -> B -> A`: every cyclic state has inbound, so
198
+ it wrongly chose an isolated terminal). A legal first transition was then reported invalid.
199
+ The initial state is now the first declared state (the canonical start).
200
+ - *Guard `redact` could stack-overflow* on a pathologically deep object (it was cycle-safe but
201
+ not depth-bounded). Since it runs in production wrapping a logger, it must never throw; it is
202
+ now depth-capped and stops descending instead of crashing.
203
+ - *`buildFocusGraph` was O(n²)* (it scanned every relationship for every frontier node); an
204
+ adjacency index makes it O(n + e). A 20k-node focus dropped from ~2s to ~85ms.
205
+ - Adds `test/hardening-edge.test.mjs`: div/zero + null-ordering regressions, a "parser never
206
+ throws on disruptive input" sweep (empty / CRLF / tabs / unicode / malformed), a CRLF
207
+ value-corruption guard, malformed-`when` and no-default runtime robustness, round-trip
208
+ fidelity, and a performance guard against the O(n²) regression.
209
+ - **One compiler for five consumers (universal `@skillstech/thunderlang/core`).** The whole
210
+ analysis layer is now Node-free, so OpenThunder (Node), the `intent` CLI (Node), SkillsTech
211
+ Studio (browser), Repo Mastery (web), and SkillsTech Mobile (React Native) run the SAME
212
+ code, not a fork. The one blocker , `emit.mjs` importing `node:crypto` for SHA-256 , is
213
+ replaced by a pure, dependency-free `hash.mjs` whose output is **byte-identical** to
214
+ `node:crypto` (proven over 2000+ cases + a known-answer test), so every existing proof,
215
+ ledger, and join-key hash is unchanged. `./core` now exports the full compiler surface
216
+ (`parseIntent`, `buildIntentGraph`, `compileSource`, `scanIntent`/`scanProject`, the scan
217
+ query views, `buildAtlas`/`searchAtlas`/`expandNode`, `buildFocusGraph`/`intentBrief`,
218
+ `diffGraphs`, `graphToSource`, `semanticDiagnostics`, `sha256`/`sha256hex`). A conformance
219
+ test statically fails CI if any module reachable from `/core` ever imports a `node:` builtin,
220
+ so the single-source-of-truth boundary cannot silently regress. Only `cli.mjs` and
221
+ `drift.mjs` (the Node entry points) touch the filesystem. The `./core` subpath now ships
222
+ TypeScript types (`core.d.ts`), and `index.d.ts` gained the scan / Fable / scan-query /
223
+ Intent Lens / Intent IR declarations, so the TypeScript consumers (OpenThunder, Repo
224
+ Mastery, SkillsTech) get full types on the shared surface , proven by a TS-consumer
225
+ typecheck in `pack:smoke`. The universal surface is also engine-safe: `hash.mjs` uses a pure
226
+ UTF-8 encoder instead of the `TextEncoder` global, so it runs on Hermes / React Native (the
227
+ conformance test now fails CI if any `/core` module references `TextEncoder`, `Buffer`, or
228
+ another non-guaranteed global, and asserts hashing works with `TextEncoder` deleted).
229
+ - **Outcome Truth , guardrails + attribution honesty on outcome contracts.** An `outcome_contract`
230
+ now takes a `guardrails` block (what must NOT regress while the target improves) and an
231
+ `attribution` (directly-measured / correlated / experiment / human / ai / unknown). Two new Fable
232
+ rules: `IL-OC-005` (a target with no guardrail is gameable , Goodhart's law) and `IL-OC-006` (no
233
+ attribution , a metric moving after release is correlation, not proof this feature caused it).
234
+ This closes the "technical success is mistaken for outcome success" gap: an outcome is only
235
+ trustworthy with a guardrail and honest attribution.
236
+ - **Change Lens , what a branch/PR changed by meaning (`intent changes`).** `intent changes
237
+ <base>..<head>` git-diffs the `.intent` files, semantic-diffs each (reusing `diffGraphs`), and
238
+ reports the behavior-level changes: guarantees / never-rules / invariants / decisions added or
239
+ removed, verification removed, and , crucially , a claim that **lost its verification** is
240
+ flagged as *weakened*. The verdict is `review` when a promise or its proof was removed or
241
+ weakened (or an approval invalidated), else `changed` / `no-semantic-change`; exit non-zero on
242
+ `review` gates a PR. Returns the touched node ids to seed a Focus Graph. `changeReport` is pure
243
+ and exported from `/core` (the CLI supplies the git-diffed graphs).
244
+ - **Global `invariant` , system-wide laws (first-class).** `invariant <Name>` declares a law that
245
+ must hold across every feature and service, not just one mission (tenant isolation, financial
246
+ consistency, "every mutation is authorized"). Fields: `statement`, `scope`, `applies_to`,
247
+ `severity`, `because`, `verify`. Compiles to a canonical `Invariant` node in `intent-graph-v1`
248
+ (additive: 40 -> 41 node types), `constrained_by` the mission, with a `verified_by` edge when a
249
+ `verify` is attached; it round-trips through graph -> source. A new Fable rule
250
+ `invariant-without-verification` warns when a global law has nothing proving it (that is exactly
251
+ where a locally-valid change silently breaks the whole system). Invariants count toward
252
+ comprehension C2 (Structured). Example: `examples/TenantIsolation.intent`.
253
+ - **Code generation , deterministic TypeScript from intent (`intent gen`).** `toTypeScript(ast)`
254
+ (`intent-codegen-v1`, no AI) generates what the intent fully determines , typed input/output
255
+ interfaces, and the **decision logic**, which is real and behaviorally identical to the runtime
256
+ evaluator (proven by a property test over the input space) , and leaves honest `TODO` markers
257
+ for business logic, annotated with the guarantees and never-rules the code must uphold. Powered
258
+ by a new `exprToJs` that translates the `when` grammar to correct JS (input-aware, so a bare
259
+ token becomes a string literal). **Now also generates C# and Java** (`--target csharp|java`):
260
+ typed records + the same first-hit decision logic, translated per language (C# `==` + `.Contains`;
261
+ Java `Objects.equals`, so string equality is value-correct, not reference `==`) via a
262
+ dialect-aware `exprToCode`. `intent gen <file> [--target typescript|csharp|java] [--out <dir>]`. Pure
263
+ / browser-safe and exported from `/core`, so the **playground now has a "Code" tab** , change
264
+ the intent, watch the code change. Completes the round-trip with `intent lift` (code -> intent).
265
+ - **Fix: non-mission root files no longer render as `# null`.** A standalone `event` / `api` /
266
+ `service` / `capability` file has no `mission`, so the graph titled its root node `null` and the
267
+ docs rendered `# null` (visible in the playground's BillingService / API / event examples). A
268
+ new `subjectName(ast)` derives the title from the primary construct, so these render under their
269
+ real name everywhere (graph, docs, generated code).
270
+ - **Comprehension Contract , the C0..C7 understanding level (`intent comprehension`).** The
271
+ measurable backbone of the Software Understanding System: `comprehensionLevel(ast)` scores how
272
+ well-understood a mission is, deterministically, from C0 (Unknown) through C4 (Verified) which
273
+ IL determines on its own, up to C5 (Observed), C6 (Teachable), and C7 (Governed) which a sibling
274
+ lifts by attaching evidence (`--observed` = OpenThunder/runtime, `--learning` = Skills Tech Talk,
275
+ `--governed` = Guardian + Workspace/Ledger). The ladder is cumulative (a gap caps the level) and
276
+ honest (a level is never claimed on evidence IL does not have; each missing rung names its owner).
277
+ `intent comprehension <file|dir>` reports the level + the next rung; `intent-comprehension-v1` is
278
+ the shared contract every product reads. Pure / browser-safe, exported from `/core`, typed.
279
+ - **Intent Lens , Intent Scope + Focus Graph (`intent focus`).** A Focus Graph is a
280
+ deterministic subgraph of the Intent Atlas around a selected scope (a mission, a feature
281
+ query, or `--nodes a,b`), with every node tagged by WHY it is in focus (selected / governing
282
+ / dependency / dependent / implementation / verification / risk / contextual) and bounded by
283
+ `--depth`. `makeScope` builds the typed Intent Scope; `buildFocusGraph` the subgraph;
284
+ `intentBrief` a deterministic what/who/guarantees/prohibitions/risks/unknowns brief whose
285
+ confidence is the weakest in scope (honesty). `intent focus <mission|query|--nodes>
286
+ [--depth N] [--json]`. Built over the existing Atlas (not a fork); pure and browser-safe so
287
+ Studio / OpenThunder / RepoMastery / Skills Tech Talk consume one focused representation.
288
+ - **Focused scanner queries (`intent risks | gaps | unverified | coverage | unknowns |
289
+ contradictions`).** Part 3 of the Intent Scanner: one deterministic question each over the
290
+ shared Intent IR + Fable findings (`scan-queries.mjs`, `intent-scan-view-v1`), so a person
291
+ can ask "what is unverified?" or "what is the verification coverage?" without reading the
292
+ whole scan report. `coverage` exits non-zero below 100%; `risks` gates on blocker/error.
293
+ Pure views, exported from the barrel.
294
+ - **IR fix: never-rules now carry their verification.** `buildIntentGraph` was emitting
295
+ `verified_by` edges for guarantees but not for attached never-rules, so the shared Intent IR
296
+ under-counted never-rule verification (and coverage read wrong). Never-rules with a `verify`
297
+ now emit `verified_by` edges + a `verify-declared` status, and `graphToSource` round-trips
298
+ them. Every downstream consumer (OpenThunder, RepoMastery) sees never-verification faithfully.
299
+ - **Code actions + autocorrect (`intent code-actions` / `apply-fix`).** `getCodeActions`
300
+ surfaces the available quick-fixes, safety-graded (`safe` autocorrects and `reviewable`
301
+ diagnostic fixes); `autocorrectSource` applies only meaning-preserving header fixes
302
+ (`goals` -> `goal`, `nevers` -> `never`, stray trailing colons), never a valid keyword
303
+ in another context (a decision's `inputs` sub-block is deliberately left alone).
304
+ `intent code-actions <file>` lists them; `intent apply-fix <file> [--write]` applies the
305
+ safe ones and reports the reviewable ones for a human. Both pure and browser-safe.
306
+ - **Per-audience docs (`intent docs --lens`).** `intent docs <file>` renders a mission as
307
+ Markdown; with `--lens <lens>` it produces an audience-specific doc that weaves that
308
+ lens's IntentLens notes inline next to the input, output, guarantee, or never they
309
+ annotate, and states up front that notes are documentation, not verification. `--out`
310
+ writes the file; otherwise it prints. `renderLensDoc` is pure and browser-safe.
311
+ - **Intent AI event sink (`intent-ai-events-v1`).** `intent ai approve` / `reject` now
312
+ persist their integration event to an append-only JSON-Lines log at
313
+ `.intent/ai-events.jsonl`, so a project keeps a durable audit trail of every AI action.
314
+ `intent ai events [dir] [--subject <id>]` reads it back (who did what, and the status
315
+ move). Pure sink module (`recordEvent`, `parseEventLog`, `serializeEventLog`, `timeline`),
316
+ exported from the barrel; rejects unknown event types; append-only (never mutates).
317
+ - **IntentLens notes CLI (`intent-notes-v1`).** `intent notes <file>` lists the compiled
318
+ `note <lens>:` blocks grouped by lens, each with its target (mission / input / output /
319
+ guarantee / never) and source line; `--lens <lens>` filters to one audience and `--json`
320
+ emits the report. Notes explain meaning for a reader and are never verification. Reuses
321
+ the parser's `ast.notes` (no new parsing).
322
+ - **Intent Ledger (`intent-ledger-v1`).** `intent ledger <file.json>` / `verifyLedger`, `record*`,
323
+ `explain` keep the append-only, hash-chained (tamper-evident) record of a project's MEANING and
324
+ history: why a mission was built, who approved it, what was assumed, which inferred intent a human
325
+ corrected, which risks were accepted, what was verified, which lessons went stale. Each entry hashes
326
+ over the previous, so history cannot be quietly rewritten , `verifyLedger` locates any break to the
327
+ entry. Deterministic (caller supplies timestamps). `intent ledger <file> --subject <id>` explains
328
+ one mission's provenance; exit non-zero on a broken chain. Browser-safe.
329
+ - **Intent Simulator (`intent-simulate-v1`).** `intent impact <base> <proposed>` / `simulateChange`
330
+ estimates a change's impact BEFORE implementation: the deterministic BLAST RADIUS (transitive
331
+ reach over the intent graph, by node type), the risk it would introduce, contradictions, and
332
+ release risk , keeping deterministic dependency impact, rule-derived risk, AI-predicted (null in
333
+ deterministic mode), and unknown impact SEPARATE and honest. Browser-safe.
334
+ - **Intent Guardian (`intent-guardian-v1`).** `intent guardian <before> <after>` / `guardianReport`
335
+ detects drift a change introduced: what changed (semantic diff by mission identity, rename-safe),
336
+ what intent it affects, the risk it INTRODUCED (findings new in after), what must be reverified
337
+ (changed contract elements + invalidated approvals), and which missions' learning is now stale.
338
+ `needs-attention` only on newly-introduced blocking risk; exit non-zero gates a PR. Browser-safe.
339
+ - **Intent Scanner + Fable (`intent-scan-v1` / `intent-fable-v1`).** `intent scan [dir]` runs the
340
+ deterministic pipeline , parse -> Intent IR -> Fable findings -> risk themes , and prints an
341
+ executive/risk summary + a highest-impact remediation sequence; `--json` for the machine report,
342
+ `--ir <path>` to emit the shared Intent IR. Fable is the rule authority OVER the diagnostics
343
+ catalog (risk category + detection strategy + remediation + suppression policy); every finding is
344
+ fully explained (never "AI detected a possible issue"). `scanProject`, `universalPack`,
345
+ `fableRuleFor`, `toFinding` exported. Browser-safe.
346
+ - **Repo-wide health report.** `intent report [dir]` / `buildReport(files)` aggregates every
347
+ .intent file into an intent-health summary (`intent-report-v1`): diagnostics by severity +
348
+ area, top codes, and coverage (guarantees verified, missions with tests, outcomes contracted).
349
+ - **SARIF code scanning.** `intent check <path> --format sarif` emits a SARIF 2.1.0 log
350
+ (`toSarif`), so diagnostics appear natively in GitHub/GitLab code scanning and SARIF-aware
351
+ IDEs , with rule metadata, level mapping, and precise line regions where known.
352
+ - **Complete diagnostics reference.** Legacy core check codes (`missing-goal`,
353
+ `guarantee-without-verification`, ...) are now documented and explainable via
354
+ `CORE_DIAGNOSTICS` / `ALL_DIAGNOSTICS`, so `intent explain <any-code>`, `intent rules`, and
355
+ `docs/diagnostics.md` cover everything the check pass emits (60 codes). A guard test keeps it
356
+ complete. The canonical `DIAGNOSTIC_RULES` stays IL-* only.
357
+ - **Canonical proof envelope (`intent-proof-v1`).** The `.intent-proof.json` shape is now a
358
+ published, versioned contract: `intentProofJsonSchema()` (JSON Schema), `validateProof()`
359
+ (dependency-free structural check), `intent proof --schema`, and a well-formedness gate in
360
+ `intent verify`. Browser-safe via `/core` so signers/renderers validate the envelope with
361
+ no Node build.
362
+ - **Browser-safe `/core` subpath**, the committed `intent-graph.schema.json`, and the
363
+ canonical 49-rule `IL-*` diagnostic catalog (60 codes documented including legacy core codes).
364
+
365
+ ### Fixed
366
+
367
+ - Deduplicated `NODE_TYPES` (`Decision` listed twice); orphan-edge fixes (Question,
368
+ transition metadata, capability/pattern/verification links) surfaced by fuzzing; a
369
+ lifecycle transition to an undefined state no longer emits a dangling edge.
370
+
371
+ ## 0.1.0
372
+
373
+ - Initial release: deterministic parse -> semantic diagnostics -> contract/architecture
374
+ graph -> implementation plan -> proof, plus docs, Mermaid, test plan, the Mission Atlas
375
+ index, IntentLift, and the approve/drift round-trip.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SkillsTech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # @skillstech/thunderlang
2
+
3
+ Deterministic ThunderLang compiler and CLI. **No AI required.** Turns a `.intent` file into
4
+ the canonical **Intent Graph** plus diagnostics, docs, a test plan, and a proof artifact,
5
+ and, for decisions, lifecycles, and outcomes, **executes the intent directly** (no code
6
+ generated). Every output is pure and deterministic: the same source always yields the same
7
+ result, so intent can be diffed, merged, tested, and trusted.
8
+
9
+ Part of [ThunderLang](https://thunderlang.dev), the intent-oriented language for AI-era software.
10
+
11
+ > Previously published as `@skillstech/intentlang`. The package was renamed to
12
+ > `@skillstech/thunderlang`; the old name remains as a deprecated alias.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install -g @skillstech/thunderlang # then: intent check path/to/Mission.intent
18
+ npx @skillstech/thunderlang help # or run without installing
19
+ ```
20
+
21
+ ## Commands
22
+
23
+ ```bash
24
+ # Author & check
25
+ intent init [Name] # scaffold a runnable starter mission
26
+ intent check <file|dir> # semantic diagnostics (exit 1 on error); a dir gates the repo
27
+ intent fmt <file|dir> -w # canonical formatting (whitespace only; comments preserved)
28
+ intent build <file> # docs, contract graph, test plan, .intent-proof.json
29
+ intent graph <file> # the canonical Intent Graph (intent-graph-v1)
30
+ intent check . --format sarif # SARIF 2.1.0 for GitHub/GitLab code scanning
31
+ intent schema # emit the graph schema + diagnostic catalog
32
+ intent rules · intent explain <CODE> # the full diagnostic catalog / one code
33
+ intent proof --schema # the canonical proof envelope schema (intent-proof-v1)
34
+
35
+ # Execute (no AI, no generated code)
36
+ intent run <file> --inputs '{"age":20}' # evaluate the decision(s) against inputs
37
+ intent simulate <file> --events submit,approve # walk the lifecycle(s)
38
+ intent test <file> # run in-file test blocks (case/scenario)
39
+ intent outcomes <file> # evaluate outcome contracts vs results
40
+ intent style <file> # resolve style intents vs the canonical token space
41
+
42
+ # Interop (9 export formats)
43
+ intent export <file> --format dmn|bpmn|smv|jsonschema|openapi|tokens|css|mermaid|playwright
44
+ intent import <file> [--format dmn|bpmn] [--json] # lift DMN/BPMN into intent
45
+ intent source <file|graph.json> # regenerate .intent from a graph
46
+ intent migrate <graph.json> [--to <ver>] # upgrade a persisted graph
47
+ intent verify <proof.json> [src] # confirm a proof matches its source
48
+
49
+ # Navigate & compare
50
+ intent atlas <dir> [--search q] intent index <dir>
51
+ intent diff <before> <after> intent merge <base> <ours> <theirs>
52
+
53
+ # Code <-> intent
54
+ intent lift <file> intent approve <file> intent drift <file>
55
+ ```
56
+
57
+ Run `intent help` for the full reference.
58
+
59
+ ## Executable intent
60
+
61
+ A decision is a runnable specification, and tests live in the same file:
62
+
63
+ ```
64
+ mission CanEnroll
65
+ decision Eligibility
66
+ inputs
67
+ age
68
+ score
69
+ rule adult
70
+ when age >= 18 and score >= 70
71
+ return Eligible
72
+ default
73
+ return NotEligible
74
+ test Eligibility
75
+ case adult
76
+ given age 20, score 90
77
+ expect Eligible
78
+ ```
79
+
80
+ ```bash
81
+ intent run mission.intent --inputs '{"age":20,"score":90}' # -> Eligible, with a trace
82
+ intent test mission.intent # -> 1/1 passed
83
+ ```
84
+
85
+ No AI, no generated code. The intent itself decides.
86
+
87
+ ## Brand as intent, checked and exported
88
+
89
+ `style_intent` models brand and visual language as a governed extension of the experience
90
+ profile: tokens bind to a **canonical, lockable address space** (off-namespace tokens are
91
+ flagged), and an `accessibility_target` is always a `proposed` claim, never asserted as met.
92
+ Export the tokens to **W3C Design Tokens**, a drop-in **CSS** sheet, the whole graph to
93
+ **Mermaid**, or an experience to a **Playwright** test scaffold.
94
+
95
+ The compiler also catches the mistakes prompts ship: a secret-typed field on an event payload
96
+ (`IL-SEC-001`), a sensitive API output with no auth (`IL-SEC-002`), a mistyped field
97
+ (`IL-TYPE-001`), and more , the full catalog is `intent rules` / [docs](https://thunderlang.dev/docs/diagnostics).
98
+
99
+ ## Use as a library
100
+
101
+ Both the CLI and the ES module share one core (ships `index.d.ts`).
102
+
103
+ ```js
104
+ import {
105
+ parseIntent, compileSource, buildIntentGraph,
106
+ evaluateDecision, simulateLifecycle, runTests, evaluateOutcomes,
107
+ toDMN, toBPMN, toJSONSchema, toOpenAPI, toDesignTokens, toCss, toMermaid, toPlaywright,
108
+ fromDMN, fromBPMN, importReport, graphToSource, migrateGraph, validateGraph,
109
+ diffGraphs, mergeGraphs, securityDiagnostics, analyzeStyle,
110
+ validateProof, intentProofJsonSchema, toSarif,
111
+ } from '@skillstech/thunderlang';
112
+
113
+ const ast = parseIntent(source);
114
+ const graph = buildIntentGraph(ast); // canonical intent-graph-v1
115
+ const run = evaluateDecision(ast.decisions[0], { age: 20 });
116
+ ```
117
+
118
+ ### One compiler, five consumers
119
+
120
+ `@skillstech/thunderlang/core` is the **universal** entry point , the whole compiler with zero
121
+ Node.js dependencies, so the *same code* runs in Node (this CLI, OpenThunder), the browser
122
+ (SkillsTech Studio, Repo Mastery web), and React Native (SkillsTech Mobile). No fork, no
123
+ re-implementation.
124
+
125
+ ```js
126
+ import {
127
+ parseIntent, buildIntentGraph, compileSource, scanProject,
128
+ buildAtlas, searchAtlas, buildFocusGraph, intentBrief, // navigate + focus (Intent Lens)
129
+ diffGraphs, graphToSource, coverageView, sha256, // the shared join-key hash
130
+ } from '@skillstech/thunderlang/core';
131
+ ```
132
+
133
+ It ships TypeScript types (`core.d.ts`), and a conformance test guarantees the surface never
134
+ gains a Node-only or engine-specific dependency (`node:` builtin, `TextEncoder`, `Buffer`, …),
135
+ so it keeps bundling everywhere. The `.` entry is this same surface plus the Node-only helpers
136
+ (the CLI, LSP, filesystem lift/drift). See
137
+ [One compiler, five consumers](https://thunderlang.dev/docs/single-compiler).
138
+
139
+ ## The Intent Graph (`intent-graph-v1`)
140
+
141
+ Compilation produces a canonical graph of 40 typed node kinds and 20 directed
142
+ relationship types, across five profiles (product, experience, system, delivery, design).
143
+ The vocabulary is closed and enforced (an anti-fork test guarantees the compiler only
144
+ emits canonical types); `intent schema` emits its draft-07 JSON Schema, also shipped as
145
+ the static `intent-graph.schema.json` in this package (CI-guaranteed in sync with the
146
+ code). Consumers (OpenThunder, Repo Mastery, SkillsTech Studio) build to this graph, and
147
+ `intent validate <graph.json>` self-checks a graph against the canonical vocabulary.
148
+
149
+ ## Output location
150
+
151
+ Artifacts are written to **`.intent/<mission-slug>/`** (not `dist/`), a committed,
152
+ scannable location: `contract-graph.json`, `architecture-graph.json`,
153
+ `implementation-plan.json`, `.intent-proof.json`, and `<mission>.md` / `.mmd` /
154
+ `.testplan.md`.
155
+
156
+ ## Status
157
+
158
+ Deterministic and tested (330+ tests: unit, property, fuzz, composition). Five-profile
159
+ language with an executable runtime, first-class tests, outcome contracts, style intent,
160
+ governance/privacy, and security/type checks; nine export adapters
161
+ (DMN/BPMN/NuSMV/JSON-Schema/OpenAPI/Design-Tokens/CSS/Mermaid/Playwright), DMN/BPMN import,
162
+ native graph<->source round-trip, schema migrations, a canonical proof envelope
163
+ (`intent-proof-v1`), and SARIF code-scanning output. Draft (pre-1.0): the language and
164
+ `intent-graph-v1` schema version independently and may still change. See the
165
+ [docs](https://thunderlang.dev/docs) and the [spec](https://thunderlang.dev/docs/spec).