@archrad/deterministic 0.1.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 (93) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/CONTRIBUTING.md +15 -0
  3. package/LICENSE +17 -0
  4. package/README.md +284 -0
  5. package/SECURITY.md +26 -0
  6. package/biome.json +25 -0
  7. package/demo-validate.gif +0 -0
  8. package/dist/cli-findings.d.ts +23 -0
  9. package/dist/cli-findings.d.ts.map +1 -0
  10. package/dist/cli-findings.js +88 -0
  11. package/dist/cli.d.ts +7 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +341 -0
  14. package/dist/edgeConfigCodeGenerator.d.ts +55 -0
  15. package/dist/edgeConfigCodeGenerator.d.ts.map +1 -0
  16. package/dist/edgeConfigCodeGenerator.js +249 -0
  17. package/dist/exportPipeline.d.ts +23 -0
  18. package/dist/exportPipeline.d.ts.map +1 -0
  19. package/dist/exportPipeline.js +65 -0
  20. package/dist/golden-bundle.d.ts +21 -0
  21. package/dist/golden-bundle.d.ts.map +1 -0
  22. package/dist/golden-bundle.js +166 -0
  23. package/dist/graphPredicates.d.ts +10 -0
  24. package/dist/graphPredicates.d.ts.map +1 -0
  25. package/dist/graphPredicates.js +33 -0
  26. package/dist/hostPort.d.ts +12 -0
  27. package/dist/hostPort.d.ts.map +1 -0
  28. package/dist/hostPort.js +39 -0
  29. package/dist/index.d.ts +22 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +21 -0
  32. package/dist/ir-lint.d.ts +11 -0
  33. package/dist/ir-lint.d.ts.map +1 -0
  34. package/dist/ir-lint.js +16 -0
  35. package/dist/ir-normalize.d.ts +48 -0
  36. package/dist/ir-normalize.d.ts.map +1 -0
  37. package/dist/ir-normalize.js +81 -0
  38. package/dist/ir-structural.d.ts +40 -0
  39. package/dist/ir-structural.d.ts.map +1 -0
  40. package/dist/ir-structural.js +267 -0
  41. package/dist/lint-graph.d.ts +40 -0
  42. package/dist/lint-graph.d.ts.map +1 -0
  43. package/dist/lint-graph.js +133 -0
  44. package/dist/lint-rules.d.ts +40 -0
  45. package/dist/lint-rules.d.ts.map +1 -0
  46. package/dist/lint-rules.js +290 -0
  47. package/dist/nodeExpress.d.ts +2 -0
  48. package/dist/nodeExpress.d.ts.map +1 -0
  49. package/dist/nodeExpress.js +528 -0
  50. package/dist/openapi-structural.d.ts +26 -0
  51. package/dist/openapi-structural.d.ts.map +1 -0
  52. package/dist/openapi-structural.js +82 -0
  53. package/dist/openapi-to-ir.d.ts +26 -0
  54. package/dist/openapi-to-ir.d.ts.map +1 -0
  55. package/dist/openapi-to-ir.js +131 -0
  56. package/dist/pythonFastAPI.d.ts +2 -0
  57. package/dist/pythonFastAPI.d.ts.map +1 -0
  58. package/dist/pythonFastAPI.js +664 -0
  59. package/dist/validate-drift.d.ts +54 -0
  60. package/dist/validate-drift.d.ts.map +1 -0
  61. package/dist/validate-drift.js +184 -0
  62. package/dist/yamlToIr.d.ts +14 -0
  63. package/dist/yamlToIr.d.ts.map +1 -0
  64. package/dist/yamlToIr.js +39 -0
  65. package/docs/CONCEPT_ADOPTION_AND_LIMITS.md +47 -0
  66. package/docs/CUSTOM_RULES.md +87 -0
  67. package/docs/ENGINEERING_NOTES.md +42 -0
  68. package/docs/IR_CONTRACT.md +54 -0
  69. package/docs/STRUCTURAL_VS_SEMANTIC_VALIDATION.md +86 -0
  70. package/fixtures/demo-direct-db-layered.json +37 -0
  71. package/fixtures/demo-direct-db-violation.json +22 -0
  72. package/fixtures/ecommerce-with-warnings.json +89 -0
  73. package/fixtures/invalid-cycle.json +15 -0
  74. package/fixtures/invalid-edge-unknown-node.json +14 -0
  75. package/fixtures/minimal-graph.json +14 -0
  76. package/fixtures/minimal-graph.yaml +13 -0
  77. package/fixtures/payment-retry-demo.json +43 -0
  78. package/llms.txt +99 -0
  79. package/package.json +84 -0
  80. package/schemas/archrad-ir-graph-v1.schema.json +67 -0
  81. package/scripts/DEMO_GIF_STORYBOARD.md +100 -0
  82. package/scripts/GIF_RECORDING_STEP_BY_STEP.md +125 -0
  83. package/scripts/README_DEMO_RECORDING.md +314 -0
  84. package/scripts/SOCIAL_POST_DRIFT_AND_INGESTION.md +17 -0
  85. package/scripts/golden-path-demo.ps1 +25 -0
  86. package/scripts/golden-path-demo.sh +23 -0
  87. package/scripts/invoke-drift-check.ps1 +16 -0
  88. package/scripts/record-demo-drift.tape +50 -0
  89. package/scripts/record-demo-payment-retry.tape +36 -0
  90. package/scripts/record-demo-validate.tape +34 -0
  91. package/scripts/record-demo.tape +33 -0
  92. package/scripts/run-demo-drift-sequence.ps1 +45 -0
  93. package/scripts/run-demo-drift-sequence.sh +41 -0
@@ -0,0 +1,125 @@
1
+ # Step-by-step: record `demo-validate.gif` (and use a branch, not `main`)
2
+
3
+ Use this when regenerating the **npm README** hero GIF (**failure-first** validate: `demo-direct-db-violation` → `demo-direct-db-layered`). For install troubleshooting, see **[README_DEMO_RECORDING.md](./README_DEMO_RECORDING.md)**.
4
+
5
+ ---
6
+
7
+ ## Part A — Git: work on a branch
8
+
9
+ Do **not** commit the new GIF (or tape tweaks) straight to `main` until reviewed.
10
+
11
+ 1. **Update local `main`** (from repo root `InkByte`):
12
+
13
+ ```bash
14
+ git fetch origin
15
+ git checkout main
16
+ git pull origin main
17
+ ```
18
+
19
+ 2. **Create a branch** (pick a name that matches your convention):
20
+
21
+ ```bash
22
+ git checkout -b chore/record-demo-validate-gif
23
+ ```
24
+
25
+ 3. **Do all recording, edits, and commits on this branch** (see Part C–D).
26
+
27
+ 4. **Open a PR** into `main` when the GIF looks right and file size is acceptable (~3–5 MB for npm).
28
+
29
+ ---
30
+
31
+ ## Part B — One-time prerequisites
32
+
33
+ - **Node.js ≥ 20** (`node -v`).
34
+ - **This monorepo** cloned; you will run commands from **`packages/deterministic`**.
35
+ - **VHS** + **ffmpeg** + **ttyd** on your `PATH` (VHS drives a headless terminal). On Windows, **Git Bash** (or WSL) is easiest because the tape uses **`Set Shell "bash"`**.
36
+
37
+ Install hints (Windows):
38
+
39
+ - `winget install charmbracelet.vhs`
40
+ - `winget install Gyan.FFmpeg`
41
+ - `winget install -e --id tsl0922.ttyd` (or Scoop: `scoop install ttyd`)
42
+
43
+ Verify:
44
+
45
+ ```bash
46
+ vhs --version
47
+ ffmpeg -version
48
+ ttyd --version
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Part C — Build CLI, then record
54
+
55
+ All steps from **`packages/deterministic`**:
56
+
57
+ 1. **Install deps** (if you have not already):
58
+
59
+ ```bash
60
+ cd packages/deterministic
61
+ npm ci
62
+ ```
63
+
64
+ 2. **Compile TypeScript** (the tape runs **`node dist/cli.js`**):
65
+
66
+ ```bash
67
+ npm run build
68
+ ```
69
+
70
+ 3. **Record the GIF** (must be **bash** — run Git Bash here if you are on Windows):
71
+
72
+ ```bash
73
+ vhs scripts/record-demo-validate.tape
74
+ ```
75
+
76
+ This writes **`demo-validate.gif`** next to **`package.json`** (`packages/deterministic/demo-validate.gif`).
77
+
78
+ 4. **If output is too fast or slow**, edit **`scripts/record-demo-validate.tape`** **`Sleep`** durations (e.g. after each `Enter`), then run **`vhs`** again.
79
+
80
+ ---
81
+
82
+ ## Part D — Check, commit on your branch, PR
83
+
84
+ 1. **Open the GIF** locally and confirm:
85
+ - First run shows **`IR-LINT-DIRECT-DB-ACCESS-002`** (and **`NO-HEALTHCHECK`**) on stderr.
86
+ - Second run ends with the **clean** success lines (no lint block).
87
+ - File size is reasonable for npm (~**< 3–5 MB** if possible).
88
+
89
+ 2. **Stage and commit** (still on your feature branch):
90
+
91
+ ```bash
92
+ git add packages/deterministic/demo-validate.gif
93
+ # include any tape/README changes you made
94
+ git status
95
+ git commit -m "chore(deterministic): regenerate demo-validate.gif (failure-first IR gate)"
96
+ ```
97
+
98
+ 3. **Push the branch** and open a **PR to `main`**:
99
+
100
+ ```bash
101
+ git push -u origin chore/record-demo-validate-gif
102
+ ```
103
+
104
+ 4. After merge, **`package.json` → `files`** already includes **`demo-validate.gif`** so it ships in the **npm** tarball.
105
+
106
+ ---
107
+
108
+ ## Optional GIFs (same package, same branch if you like)
109
+
110
+ | Tape | Output |
111
+ |------|--------|
112
+ | **`scripts/record-demo.tape`** | **`demo.gif`** (minimal export + file list) |
113
+ | **`scripts/record-demo-payment-retry.tape`** | **`demo-payment-retry.gif`** |
114
+ | **`scripts/record-demo-drift.tape`** | **`demo-drift.gif`** (**`validate-drift`** trust tape) |
115
+ | **`scripts/record-demo-validate.tape`** | **`demo-validate.gif`** (README hero) |
116
+
117
+ ---
118
+
119
+ ## Quick reference — what the tape runs
120
+
121
+ 1. `node dist/cli.js validate -i fixtures/demo-direct-db-violation.json`
122
+ 2. Comment + `node dist/cli.js validate -i fixtures/demo-direct-db-layered.json`
123
+ 3. Short comment about **`--fail-on-warning`** / **`--json`**
124
+
125
+ Fixtures live under **`packages/deterministic/fixtures/`**.
@@ -0,0 +1,314 @@
1
+ # Recording the **npm README** demo GIF
2
+
3
+ **Scope:** the README for **`@archrad/deterministic`** on **npmjs.com** (package root **`README.md`**).
4
+ **Storyboard:** [DEMO_GIF_STORYBOARD.md](./DEMO_GIF_STORYBOARD.md) — one recommended hero GIF.
5
+ **Step-by-step (Git branch + VHS + commit):** [GIF_RECORDING_STEP_BY_STEP.md](./GIF_RECORDING_STEP_BY_STEP.md).
6
+
7
+ ## Recommended: `demo-validate.gif`
8
+
9
+ **Story:** **failure first** — **`fixtures/demo-direct-db-violation.json`** → **`IR-LINT-DIRECT-DB-ACCESS-002`** (and **NO-HEALTHCHECK**) → layered **`fixtures/demo-direct-db-layered.json`** → **clean** validate. **No `export`** in the tape. **IR-LINT** lines use **ANSI red** when **stderr is a TTY** (unset **`NO_COLOR`**); VHS/ttyd counts as a TTY.
10
+
11
+ From **`packages/deterministic`**. The **`.tape`** files expect **bash** (Git Bash, WSL, or macOS/Linux). On **PowerShell alone**, `vhs` is not installed until you add it to `PATH` (see below).
12
+
13
+ ### When VHS fails
14
+
15
+ VHS shells out to **`ttyd`** + **`ffmpeg`**; installs differ, and some environments block or hang headless terminals.
16
+
17
+ | Symptom | Things to try |
18
+ |--------|----------------|
19
+ | **`echo`: executable file not found** | VHS **`Require echo`** checks a real `echo` binary. Our **`record-demo-drift.tape`** omits it; for other tapes, delete the **`Require echo`** line or run VHS from **Git Bash** where **`echo`** exists. |
20
+ | **`ttyd` / `ffmpeg` not found** | Install both, **restart the terminal**, confirm **`ttyd --version`** and **`ffmpeg -version`**. |
21
+ | **Black screen, hang, or instant failure** | Update VHS; run from **Git Bash**; try WSL2; temporarily reduce **`Set Width` / `Set Height`** in the `.tape`. |
22
+ | **You want to skip VHS entirely** | Use the **same command sequence** as the tape while screen-recording (see below). |
23
+
24
+ **Drift GIF without VHS:** from **`packages/deterministic`**, start **ShareX** (GIF) / **OBS** / **ScreenToGif**, then run one of:
25
+
26
+ ```bash
27
+ # Git Bash / WSL / macOS / Linux
28
+ bash scripts/run-demo-drift-sequence.sh
29
+ # Optional slower pacing: DEMO_DRIFT_PAUSE=4 bash scripts/run-demo-drift-sequence.sh
30
+ ```
31
+
32
+ ```powershell
33
+ # Windows PowerShell (from packages/deterministic)
34
+ powershell -ExecutionPolicy Bypass -File scripts/run-demo-drift-sequence.ps1
35
+ ```
36
+
37
+ Trim the recording and export to GIF (ShareX can save directly to GIF; otherwise **`ffmpeg`** as in [Manual recording (no VHS)](#manual-recording-no-vhs) below). The **`.tape`** file remains the spec; the scripts are the **portable replay** for capture tools.
38
+
39
+ **asciinema** (terminal cast, then GIF with **[agg](https://github.com/asciinema/agg)**): `asciinema rec demo.cast`, run the same commands (or `bash scripts/run-demo-drift-sequence.sh` inside the session), then `agg demo.cast demo-drift.gif`.
40
+
41
+ ### Install VHS on Windows
42
+
43
+ [VHS](https://github.com/charmbracelet/vhs) needs **`ffmpeg`** and **`ttyd`** on your `PATH`.
44
+
45
+ - **`ffmpeg is not installed`** → install ffmpeg (e.g. `winget install Gyan.FFmpeg`), restart terminal, `ffmpeg -version`.
46
+ - **`ttyd is not installed`** → `winget install -e --id tsl0922.ttyd` or `scoop install ttyd`, restart terminal, `ttyd --version`.
47
+
48
+ Typical paths:
49
+
50
+ 1. **winget** (run in **elevated** PowerShell if prompted):
51
+ ```powershell
52
+ winget install charmbracelet.vhs
53
+ winget install Gyan.FFmpeg
54
+ winget install -e --id tsl0922.ttyd
55
+ ```
56
+ If **winget** has no **ttyd** package on your machine, use [ttyd releases](https://github.com/tsl0922/ttyd/releases) or **Scoop**: `scoop install ttyd`.
57
+
58
+ 2. **Scoop** (user install):
59
+ ```powershell
60
+ scoop install vhs ffmpeg ttyd
61
+ ```
62
+
63
+ 3. **Go** (puts `vhs.exe` in `%USERPROFILE%\go\bin` — add that folder to PATH):
64
+ ```powershell
65
+ go install github.com/charmbracelet/vhs@latest
66
+ ```
67
+
68
+ Close and reopen the terminal, then:
69
+
70
+ ```bash
71
+ npm run build
72
+ vhs scripts/record-demo-validate.tape
73
+ ```
74
+
75
+ If `vhs` still says “not recognized”, run `where.exe vhs` or use the full path to `vhs.exe`. Easiest path on Windows is often **Git Bash** after install, since the tape uses `Set Shell "bash"`.
76
+
77
+ Writes **`demo-validate.gif`** next to **`package.json`**. Add to **`README.md`** (below the title block):
78
+
79
+ ```markdown
80
+ ![archrad validate — IR-LINT-DIRECT-DB-ACCESS-002 first, fix on the graph, clean gate](demo-validate.gif)
81
+ ```
82
+
83
+ **`package.json` → `files`** already lists **`demo-validate.gif`** so it ships in the **npm tarball** once the file exists (commit the GIF or generate before publish).
84
+
85
+ Tweak **`Sleep`** in **`record-demo-validate.tape`** if the output scrolls too fast or slow. Target **< ~3–5 MB** for npm/GitHub.
86
+
87
+ ## Optional second GIF (`demo.gif`)
88
+
89
+ Export + listing generated files (no Docker in tape):
90
+
91
+ ```bash
92
+ vhs scripts/record-demo.tape
93
+ ```
94
+
95
+ Use only if you need a second motion graphic; prefer **one** GIF on npm.
96
+
97
+ ## Phase A — payment + retry → FastAPI (`demo-payment-retry.gif`)
98
+
99
+ Golden fixture **`fixtures/payment-retry-demo.json`**, validate + export + **`grep`** on **`app/main.py`** for **`maxAttempts`**. Storyboard: **`DEMO_GIF_STORYBOARD.md`** (Phase A). From **`packages/deterministic`** (bash):
100
+
101
+ ```bash
102
+ npm run build
103
+ vhs scripts/record-demo-payment-retry.tape
104
+ ```
105
+
106
+ Writes **`demo-payment-retry.gif`** next to **`package.json`**. Not included in the default npm README hero slot unless you choose to ship it (watch tarball size).
107
+
108
+ ## Deterministic drift (`demo-drift.gif`)
109
+
110
+ **`validate-drift`** after a deliberate edit to **`./out/app/main.py`** — see **`DEMO_GIF_STORYBOARD.md`**.
111
+
112
+ **Automated (VHS):** from **`packages/deterministic`**:
113
+
114
+ ```bash
115
+ npm run record:demo:drift
116
+ ```
117
+
118
+ **Manual capture (no VHS):** **`scripts/run-demo-drift-sequence.sh`** or **`scripts/run-demo-drift-sequence.ps1`** — see [When VHS fails](#when-vhs-fails) above.
119
+
120
+ Writes **`demo-drift.gif`** next to **`package.json`** when you export from your recorder. **`package.json` → `files`** includes **`demo-drift.gif`** when you publish.
121
+
122
+ ---
123
+
124
+ ## Trust loop drift (IDE + terminal)
125
+
126
+ For **skeptic-grade** drift marketing, show **edit → save → drift**, *and* bookend with **green** **`validate-drift`** before and after so it is not “only a failure.” Storyboard: **[DEMO_GIF_STORYBOARD.md](./DEMO_GIF_STORYBOARD.md)** (**Trust loop**). Tools: **ShareX**, **ScreenStudio**, **OBS**.
127
+
128
+ ### Complete GIF — step by step (baseline OK → break → fail → fix → OK again)
129
+
130
+ Use **`packages/deterministic`**. Replace **`C:\scm\InkByte`** with your path.
131
+
132
+ **Drift check — pick one (avoids “Invoke-DriftCheck not recognized”):**
133
+
134
+ 1. **Script (works in every new terminal)** — from **`packages/deterministic`**:
135
+
136
+ ```powershell
137
+ .\scripts\invoke-drift-check.ps1
138
+ ```
139
+
140
+ 2. **One-liner (paste anytime, same folder):**
141
+
142
+ ```powershell
143
+ node dist/cli.js validate-drift -i fixtures/payment-retry-demo.json -t python -o ./out --skip-host-port-check --skip-ir-lint
144
+ ```
145
+
146
+ 3. **Function (only in the same PowerShell session where you defined it):** if you use **`Invoke-DriftCheck`**, you must paste the **`function Invoke-DriftCheck { ... }`** block **in that same window** before calling it; **new tabs** do not keep the function.
147
+
148
+ **Before you record — rehearsal (optional):** run steps 1–4 once without ShareX so timings feel natural.
149
+
150
+ ---
151
+
152
+ **Step 1 — Install / configure capture**
153
+ - **ShareX:** **Task settings → Capture → Screen recording → GIF**; assign **record region** hotkey.
154
+ - Or **OBS** / **Game Bar** → MP4 → **`ffmpeg`** (see [Manual recording](#manual-recording-no-vhs)).
155
+
156
+ **Step 2 — Layout**
157
+ IDE (**VS Code** / **Cursor**) + **Windows Terminal** (PowerShell) visible together (**split screen** = one ShareX region covers both).
158
+
159
+ **Pasting commands (read this)**
160
+ If you copy several lines and they end up **on one line** (e.g. `...deterministicnpm run build...` or `SilentlyContinuenode dist...`), PowerShell breaks and you may see **`Set-Location : Parameter name 'i' is ambiguous`** — the shell is no longer running **`node dist/cli.js export -i ...`** as intended. **Fix:** press **Enter after each line**, or paste the **single-line** version below (semicolons separate statements).
161
+
162
+ **Step 3 — Prep export (off-camera or start of clip)**
163
+
164
+ Run **one line at a time**, or use this **paste-safe one-liner** (change the path if needed):
165
+
166
+ ```powershell
167
+ Set-Location C:\scm\InkByte\packages\deterministic; npm run build; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; Remove-Item -Recurse -Force .\out -ErrorAction SilentlyContinue; node dist/cli.js export -i fixtures/payment-retry-demo.json -t python -o ./out --skip-host-port-check --skip-ir-lint
168
+ ```
169
+
170
+ Multi-line (only if each line executes separately):
171
+
172
+ ```powershell
173
+ Set-Location C:\scm\InkByte\packages\deterministic
174
+ npm run build
175
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
176
+ Remove-Item -Recurse -Force .\out -ErrorAction SilentlyContinue
177
+ node dist/cli.js export -i fixtures/payment-retry-demo.json -t python -o ./out --skip-host-port-check --skip-ir-lint
178
+ ```
179
+
180
+ **Step 4 — Find the line you will edit (rehearsal)**
181
+
182
+ ```powershell
183
+ Select-String -Path .\out\app\main.py -Pattern "maxAttempts|max_attempts|retry" | Select-Object -First 10 LineNumber, Line
184
+ ```
185
+
186
+ Pick one line (e.g. **`max_attempts`** / retry **`3`** → you will temporarily change to **`1`**).
187
+
188
+ **Step 5 — Start recording**
189
+ ShareX **region** around IDE + terminal (or full screen for quick-cut editing later).
190
+
191
+ **Step 6 — Act A: export success (terminal)**
192
+ If you did not show export in step 3 on camera, run the **`export`** block from step 3 now. Pause ~2s on **`archrad: wrote … files`** / success text.
193
+
194
+ **Step 7 — Act B: baseline drift check = success**
195
+
196
+ ```powershell
197
+ .\scripts\invoke-drift-check.ps1
198
+ ```
199
+
200
+ (or the **one-liner** under *Drift check — pick one* above.)
201
+
202
+ **Expect:** exit code **0** and a line like **`no deterministic drift`**. This proves the tool **passes** when disk matches IR. Hold ~2–3s on screen.
203
+
204
+ **Step 8 — Act C: open editor**
205
+
206
+ ```powershell
207
+ code .\out\app\main.py
208
+ ```
209
+
210
+ (or open the file manually). Scroll so the target line is visible.
211
+
212
+ **Step 9 — Act D: the edit + save**
213
+ Change the value (e.g. **`3` → `1`**) or another obvious edit on that line → **Ctrl+S**. Pause ~1s.
214
+
215
+ **Step 10 — Act E: drift check = failure**
216
+
217
+ ```powershell
218
+ .\scripts\invoke-drift-check.ps1
219
+ ```
220
+
221
+ **Expect:** **`DRIFT-MODIFIED`** / **`app/main.py`**, non-zero exit. Hold ~3s so viewers read it.
222
+
223
+ **Step 11 — Act F: fix (pick one)**
224
+
225
+ - **F1 — Undo in editor (best for “same tree” story):** **Ctrl+Z** until the line matches the export again → **Ctrl+S**.
226
+ - **F2 — Re-export (regenerate story):** in terminal (one line, paste-safe):
227
+
228
+ ```powershell
229
+ Remove-Item -Recurse -Force .\out -ErrorAction SilentlyContinue; node dist/cli.js export -i fixtures/payment-retry-demo.json -t python -o ./out --skip-host-port-check --skip-ir-lint
230
+ ```
231
+
232
+ If you used **F2**, optionally show **IDE** refreshing **`main.py`** (reload from disk) so the number is **3** again.
233
+
234
+ **Step 12 — Act G: drift check = success again**
235
+
236
+ ```powershell
237
+ .\scripts\invoke-drift-check.ps1
238
+ ```
239
+
240
+ **Expect:** exit **0**, **`no deterministic drift`** again. Hold ~2–3s — this is the **success case** that closes the loop.
241
+
242
+ **Step 13 — Stop recording**
243
+ Trim dead air at start/end; if the GIF is huge, lower fps or shorten pauses in ShareX/ffmpeg. Save as **`demo-drift-trust-loop-full.gif`** (or your name).
244
+
245
+ **Step 14 — Sanity check**
246
+ Watch once: **green → edit → red → fix → green**. If **red** never appears, the edit did not change bytes the export cares about; pick another line or use **`echo '# x' >> .\out\app\main.py`** only for the break (less “architectural” but still valid **DRIFT-MODIFIED**).
247
+
248
+ ---
249
+
250
+ **Notes:** Substitute **`archrad`** for **`node dist/cli.js`** if the CLI is on **`PATH`**. Do not set **`NO_COLOR`** if you want red stderr. Terminal-only variant (no IDE): run **step 3**, then **7**, append a line with **`Add-Content`**, **10**, delete **`out`** and **export** again, **12** — still a full arc, weaker causality; see **`scripts/run-demo-drift-sequence.ps1`** for a partial terminal-only path (extend locally with a final **`validate-drift`** after you revert).
251
+
252
+ ## Manual recording (no VHS)
253
+
254
+ Works in **PowerShell** — no `vhs` required. Run the command, then capture the terminal:
255
+
256
+ | Tool | Notes |
257
+ |------|--------|
258
+ | **ShareX** (free) | [getsharex.com](https://getsharex.com/) — can record **directly to GIF**. |
259
+ | **Xbox Game Bar** | `Win+G` → record → **MP4**; convert with **ffmpeg** (see below). |
260
+ | **Snipping Tool** (Win11) | **Record** if available → video → ffmpeg → GIF. |
261
+ | **ScreenToGif** | Optional; not required. |
262
+
263
+ **MP4 → GIF** (after Game Bar / OBS; requires **ffmpeg** on PATH):
264
+
265
+ ```powershell
266
+ ffmpeg -i recording.mp4 -vf "fps=10,scale=800:-1:flags=lanczos" -loop 0 demo-validate.gif
267
+ ```
268
+
269
+ **PowerShell:**
270
+
271
+ ```powershell
272
+ cd C:\path\to\packages\deterministic
273
+ npm run build
274
+ node dist/cli.js validate -i fixtures/demo-direct-db-violation.json
275
+ node dist/cli.js validate -i fixtures/demo-direct-db-layered.json
276
+ ```
277
+
278
+ **Bash / Git Bash:**
279
+
280
+ ```bash
281
+ npm run build
282
+ node dist/cli.js validate -i fixtures/demo-direct-db-violation.json
283
+ node dist/cli.js validate -i fixtures/demo-direct-db-layered.json
284
+ ```
285
+
286
+ ---
287
+
288
+ ## Full golden path (not for npm README hero)
289
+
290
+ **`archrad export`** → **`make run`** → **`curl`** → **422** on **`/signup`** — good for docs or video; Docker makes README GIFs long. Commands:
291
+
292
+ ```bash
293
+ npm run build
294
+ node dist/cli.js export --ir fixtures/minimal-graph.json --target python --out ./out
295
+ cd ./out && make run
296
+ ```
297
+
298
+ ```bash
299
+ curl -sS -w "\nHTTP %{http_code}\n" -X POST http://localhost:8080/signup \
300
+ -H "Content-Type: application/json" -d '{}'
301
+ ```
302
+
303
+ Or **`bash scripts/golden-path-demo.sh`** / **`pwsh -File scripts/golden-path-demo.ps1`** for export + reminders.
304
+
305
+ ## Other tools
306
+
307
+ | Tool | Notes |
308
+ |------|-------|
309
+ | **[VHS](https://github.com/charmbracelet/vhs)** | `.tape` → GIF; **`record-demo-validate.tape`**, **`record-demo.tape`**. |
310
+ | **[asciinema](https://asciinema.org/)** + **[agg](https://github.com/asciinema/agg)** | Terminal → GIF. |
311
+
312
+ ## CI / repo size
313
+
314
+ Avoid multi‑MB GIFs without **Git LFS** if your policy requires it; npm and GitHub READMEs are usually fine under a few MB.
@@ -0,0 +1,17 @@
1
+ # Draft reply: drift + “where does the IR come from?”
2
+
3
+ Use as a Reddit (or similar) follow-up after the drift thread. Trim voice to match your account.
4
+
5
+ ---
6
+
7
+ **On drift:** The enforcement story is not “hope people read the docs.” It’s **gate the blueprint artifact**. You run **`archrad validate`** on the **IR** in CI (or pre-commit): the linter fires on the graph — e.g. **`IR-LINT-DIRECT-DB-ACCESS-002`** when an HTTP node talks straight to a datastore — **before** you generate or ship code. The fix is **an edit to the IR** (introduce a service layer, health route, etc.), then the gate passes. Same loop you’d want for any contract-first workflow: **blueprint in → violation found → fix on the graph → gate passes**. No generated-code diff required for that 30-second story.
8
+
9
+ **On “where does the IR come from?”** Fair question for any real team. Today the honest answer is **multiple on-ramps**: hand-authored JSON/YAML graph, **`archrad yaml-to-ir`**, and **`archrad ingest openapi`** (OpenAPI 3.x → HTTP-shaped IR — structural surface, not full system semantics). **That ingestion path is the part we’re actively building out** (OpenAPI, and toward **IaC / other specs** as inputs), with **manual IR** as the **starting point**, not the end state. Stating that clearly tends to turn “but where does IR come from?” into **someone following the journey** instead of **blocking on a strawman permanent end state**.
10
+
11
+ ---
12
+
13
+ Optional one-liner for the post body: *IR from OpenAPI ingest + YAML graph today; more ingestion sources in progress — validate runs on whatever lands in the repo as the blueprint.*
14
+
15
+ ---
16
+
17
+ **Internal / roadmap:** OSS **`archrad validate-drift`** and Cloud **`POST /api/v1/deterministic/drift-check`** are the **thin** deterministic drift checks; dashboard KPI + **SYNC** remain roadmap — **`docs/PHASE_B_C_DRIFT_AND_OSS_REGEN.md`**.
@@ -0,0 +1,25 @@
1
+ # Golden-path demo commands (README / GIF). Run from packages/deterministic.
2
+ param([string] $OutDir = "golden-path-out")
3
+
4
+ $ErrorActionPreference = "Stop"
5
+ $Root = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
6
+ Set-Location $Root
7
+
8
+ Write-Host ">>> npm run build"
9
+ npm run build
10
+
11
+ $out = Join-Path $Root $OutDir
12
+ if (Test-Path $out) { Remove-Item -Recurse -Force $out }
13
+
14
+ Write-Host ">>> archrad export -> $OutDir"
15
+ node dist/cli.js export --ir fixtures/minimal-graph.json --target python --out $out
16
+
17
+ Write-Host ""
18
+ Write-Host "=== Next (terminal 1) ==="
19
+ Write-Host " cd $out"
20
+ Write-Host " make run"
21
+ Write-Host ""
22
+ Write-Host "=== Next (terminal 2) ==="
23
+ Write-Host " curl -sS -X POST http://localhost:8080/signup -H `"Content-Type: application/json`" -d '{}'"
24
+ Write-Host ""
25
+ Write-Host "Expect HTTP 422 or 400 with a structured error body."
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+ # Commands for a ~60s golden-path demo (and README / HN GIF recording).
3
+ # Run from packages/deterministic after: npm run build
4
+
5
+ set -euo pipefail
6
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
7
+ cd "$ROOT"
8
+
9
+ OUT="${1:-./golden-path-out}"
10
+ echo ">>> npm run build"
11
+ npm run build
12
+ echo ">>> rm -rf $OUT && archrad export"
13
+ rm -rf "$OUT"
14
+ node dist/cli.js export --ir fixtures/minimal-graph.json --target python --out "$OUT"
15
+
16
+ echo ""
17
+ echo "=== Next (terminal 1) — start the stack ==="
18
+ echo " cd $(pwd)/$OUT && make run"
19
+ echo ""
20
+ echo "=== Next (terminal 2) — validation smoke ==="
21
+ echo " curl -sS -X POST http://localhost:8080/signup -H 'Content-Type: application/json' -d '{}'"
22
+ echo ""
23
+ echo "Expect HTTP 422 or 400 with a structured error body (not 500)."
@@ -0,0 +1,16 @@
1
+ # Payment-retry fixture drift check (same flags as trust-loop docs).
2
+ # From packages/deterministic:
3
+ # .\scripts\invoke-drift-check.ps1
4
+ # Or from anywhere:
5
+ # powershell -ExecutionPolicy Bypass -File path\to\packages\deterministic\scripts\invoke-drift-check.ps1
6
+
7
+ $ErrorActionPreference = "Stop"
8
+ $pkgRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
9
+ Set-Location $pkgRoot
10
+
11
+ & node dist/cli.js validate-drift `
12
+ -i fixtures/payment-retry-demo.json `
13
+ -t python -o ./out `
14
+ --skip-host-port-check --skip-ir-lint
15
+
16
+ exit $LASTEXITCODE
@@ -0,0 +1,50 @@
1
+ # OSS trust tape: export → tamper generated file → validate-drift catches DRIFT-MODIFIED.
2
+ # Same CLI as global `archrad` when linked; tape uses `node dist/cli.js` for clone-local reproducibility.
3
+ # Prereq: bash (Git Bash / WSL). From packages/deterministic:
4
+ # npm run record:demo:drift
5
+ # or: npm run build && vhs scripts/record-demo-drift.tape
6
+ # If VHS/ttyd fails on your machine: run scripts/run-demo-drift-sequence.sh (Git Bash) or
7
+ # scripts/run-demo-drift-sequence.ps1 while capturing the terminal (ShareX, OBS, etc.) — see README_DEMO_RECORDING.md
8
+
9
+ Output demo-drift.gif
10
+
11
+ Set Shell "bash"
12
+ Set FontSize 16
13
+ Set Width 1200
14
+ Set Height 720
15
+ Set Padding 20
16
+ Set Theme "Catppuccin Mocha"
17
+
18
+ Hide
19
+ Type "clear" Enter
20
+ Type "rm -rf ./out" Enter
21
+ Show
22
+
23
+ Sleep 400ms
24
+ Type "# Deterministic drift: on-disk export vs fresh export from the same IR" Sleep 120ms Enter
25
+ Sleep 350ms
26
+ Type "npm run build && node dist/cli.js export -i fixtures/payment-retry-demo.json -t python -o ./out --skip-host-port-check --skip-ir-lint" Sleep 100ms Enter
27
+ Sleep 500ms
28
+ Sleep 4s
29
+
30
+ Type "# out/app/main.py — tail before tamper (generated, matches IR)" Sleep 120ms Enter
31
+ Sleep 300ms
32
+ Type "tail -n 10 ./out/app/main.py" Sleep 100ms Enter
33
+ Sleep 3s
34
+
35
+ Type "# Tamper: append one line (IR file on disk is unchanged)" Sleep 120ms Enter
36
+ Sleep 400ms
37
+ Type "echo '# Drift introduced' >> ./out/app/main.py" Sleep 100ms Enter
38
+ Sleep 2s
39
+
40
+ Type "# Same file — tail after (extra line is the only change)" Sleep 120ms Enter
41
+ Sleep 300ms
42
+ Type "tail -n 12 ./out/app/main.py" Sleep 100ms Enter
43
+ Sleep 3s
44
+
45
+ Type "node dist/cli.js validate-drift -i fixtures/payment-retry-demo.json -t python -o ./out --skip-host-port-check --skip-ir-lint" Sleep 100ms Enter
46
+ Sleep 500ms
47
+ Sleep 4s
48
+
49
+ Type "# Fix: re-export from IR (or revert the file) — then validate-drift is clean again" Sleep 100ms Enter
50
+ Sleep 2s
@@ -0,0 +1,36 @@
1
+ # Phase A demo: golden payment + retry IR → FastAPI export → show emitted retry in main.py
2
+ # Requires bash (Git Bash / WSL). From packages/deterministic:
3
+ # npm run build && vhs scripts/record-demo-payment-retry.tape
4
+ # Voiceover (not in tape): IR is source of truth; editing generated code diverges —
5
+ # see record-demo-drift.tape → demo-drift.gif for validate-drift catching tampering.
6
+
7
+ Output demo-payment-retry.gif
8
+
9
+ Require echo
10
+
11
+ Set Shell "bash"
12
+ Set FontSize 16
13
+ Set Width 1200
14
+ Set Height 640
15
+ Set Padding 20
16
+ Set Theme "Catppuccin Mocha"
17
+
18
+ Hide
19
+ Type "clear" Enter
20
+ Show
21
+
22
+ Sleep 500ms
23
+ Type "# Golden IR: fixtures/payment-retry-demo.json (edge retry + node retryPolicy)" Sleep 200ms Enter
24
+ Sleep 400ms
25
+ Type "npm run build && node dist/cli.js validate -i fixtures/payment-retry-demo.json" Sleep 100ms Enter
26
+ Sleep 3s
27
+
28
+ Type "node dist/cli.js export -i fixtures/payment-retry-demo.json -t python -o ./demo-payment-retry-out --skip-host-port-check" Sleep 100ms Enter
29
+ Sleep 200ms
30
+ Sleep 4s
31
+
32
+ Type "grep -n 'maxAttempts' demo-payment-retry-out/app/main.py | head -6" Sleep 100ms Enter
33
+ Sleep 3s
34
+
35
+ Type "# Voiceover: delete retry in generated code → IR still encodes 3; re-run export to restore" Sleep 100ms Enter
36
+ Sleep 2s
@@ -0,0 +1,34 @@
1
+ # Hero README GIF: failure-first validate loop (IR gate before codegen).
2
+ # IR-LINT-DIRECT-DB-ACCESS-002 on violation → same intent, layered graph → clean validate.
3
+ # Prereq: npm run build. From packages/deterministic (bash):
4
+ # vhs scripts/record-demo-validate.tape
5
+ # → demo-validate.gif (stderr uses red IR-LINT lines when TTY — VHS/ttyd is TTY)
6
+
7
+ Output demo-validate.gif
8
+ Require echo
9
+
10
+ Set Shell "bash"
11
+ Set FontSize 16
12
+ Set Width 1200
13
+ Set Height 720
14
+ Set Padding 20
15
+ Set Theme "Catppuccin Mocha"
16
+
17
+ Hide
18
+ Type "clear" Enter
19
+ Show
20
+
21
+ Sleep 350ms
22
+ Type "# Validate the blueprint IR — enforcement on the artifact (not on prose)" Sleep 120ms Enter
23
+ Sleep 350ms
24
+ Type "node dist/cli.js validate -i fixtures/demo-direct-db-violation.json" Sleep 100ms Enter
25
+ Sleep 5s
26
+
27
+ Type "# Fix the graph: service between API and DB + /health (see demo-direct-db-layered.json)" Sleep 100ms Enter
28
+ Sleep 2s
29
+
30
+ Type "node dist/cli.js validate -i fixtures/demo-direct-db-layered.json" Sleep 100ms Enter
31
+ Sleep 4s
32
+
33
+ Type "# CI: archrad validate --fail-on-warning | JSON: --json" Sleep 100ms Enter
34
+ Sleep 2s
@@ -0,0 +1,33 @@
1
+ # Record a README GIF with VHS: https://github.com/charmbracelet/vhs
2
+ # Run from packages/deterministic (bash available): vhs scripts/record-demo.tape
3
+ # → writes demo.gif next to package.json (packages/deterministic)
4
+ # From monorepo root: cd packages/deterministic && vhs scripts/record-demo.tape
5
+
6
+ Output demo.gif
7
+ Require echo
8
+
9
+ Set Shell "bash"
10
+ Set FontSize 16
11
+ Set Width 1200
12
+ Set Height 600
13
+ Set Padding 20
14
+ Set Theme "Catppuccin Mocha"
15
+
16
+ Hide
17
+ Type "clear" Enter
18
+ Show
19
+
20
+ Sleep 500ms
21
+ Type "# Build + export (golden path demo)" Sleep 200ms Enter
22
+ Sleep 300ms
23
+ Type "npm run build && node dist/cli.js export --ir fixtures/minimal-graph.json --target python --out ./demo-gif-out --skip-host-port-check" Sleep 100ms Enter
24
+ Sleep 4s
25
+
26
+ Type "ls demo-gif-out | head -8" Sleep 100ms Enter
27
+ Sleep 2s
28
+
29
+ Type "# Next: cd demo-gif-out && make run (Docker)" Sleep 100ms Enter
30
+ Sleep 1s
31
+
32
+ Type "# Then: curl -X POST http://localhost:8080/signup -H 'Content-Type: application/json' -d '{}'" Sleep 100ms Enter
33
+ Sleep 2s