run-demo.sh
bash
sha256:8915fe406161f95c1681f9469375e7bae5b28c884f00bedbdef65e4b0cd0738d
docs(flow): commit FLOW-V0-SPEC.md hygiene for 7A-INT merge
Human
17 hours ago
| 1 | #!/usr/bin/env bash |
| 2 | # |
| 3 | # Anti-drift diff demo (Phase 7A, Step 7A-12) — reproducible driver. |
| 4 | # |
| 5 | # Proves the FLOW-PROJECTION-GENERATOR-CONTRACT-7A-11 §10 acceptance bar end-to-end against |
| 6 | # our own repo guidance, using the real `knowtation flow project` CLI: |
| 7 | # 1. Generate marker-first, ordered, secret-free artifacts from a canonical Flow. |
| 8 | # 2. Edit canonical + bump version -> regenerate -> diff shows ONLY the canonical change. |
| 9 | # 3. Delete the artifact -> regenerate -> reproduced byte-for-byte. |
| 10 | # 4. Hand-edit the artifact -> `--check` reports drift and exits non-zero. |
| 11 | # 5. Canonical ahead of a pinned artifact -> `--check` reports stale and exits non-zero. |
| 12 | # 6. Fidelity is honest (cursor_rule drops `when_not_to_run`; cli_runbook expresses it). |
| 13 | # |
| 14 | # Scope fence (7A-12): demo only. The shipped `flows/starter/` bundles, the live data store, |
| 15 | # the real `AGENTS.md`, and `.cursor/rules/` are NOT touched — the demo runs against copied |
| 16 | # starter bundles (`demo-starters/v1`,`/v2`) and a throwaway data store (mktemp). |
| 17 | set -uo pipefail |
| 18 | |
| 19 | REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" |
| 20 | cd "$REPO_ROOT" |
| 21 | |
| 22 | EV="docs/evidence/7A-12" |
| 23 | ART="$EV/artifacts" |
| 24 | V1="$EV/demo-starters/v1" |
| 25 | V2="$EV/demo-starters/v2" |
| 26 | STORE_ROOT="$(mktemp -d)" |
| 27 | export KNOWTATION_DATA_DIR="$STORE_ROOT/data" |
| 28 | mkdir -p "$KNOWTATION_DATA_DIR" "$ART" |
| 29 | |
| 30 | TRANSCRIPT="$ART/transcript.txt" |
| 31 | : > "$TRANSCRIPT" |
| 32 | |
| 33 | log() { printf '%s\n' "$*" | tee -a "$TRANSCRIPT"; } |
| 34 | run() { # run <label> <cmd...> — records cmd, output, and exit code (never aborts the driver) |
| 35 | local label="$1"; shift |
| 36 | log "" |
| 37 | log "### $label" |
| 38 | log "\$ $*" |
| 39 | "$@" >>"$TRANSCRIPT" 2>&1 |
| 40 | local rc=$? |
| 41 | log "[exit=$rc]" |
| 42 | return 0 |
| 43 | } |
| 44 | |
| 45 | FLOW="flow_overseer_handover" |
| 46 | |
| 47 | log "=== Anti-drift diff demo (7A-12) ===" |
| 48 | log "store: $KNOWTATION_DATA_DIR" |
| 49 | |
| 50 | # --- Stage A: seed canonical v0.1.0 into a clean store ------------------------------------- |
| 51 | node -e "import('./lib/flow/flow-store.mjs').then(m=>{const r=m.seedStarterFlows(process.env.KNOWTATION_DATA_DIR,'default',{starterDir:'$V1'});console.log('seed v1',JSON.stringify(r));})" | tee -a "$TRANSCRIPT" |
| 52 | |
| 53 | # (1) Generate baseline artifacts from canonical v0.1.0 |
| 54 | run "1a. generate cursor_rule @ v0.1.0" \ |
| 55 | node cli/index.mjs flow project "$FLOW" --harness cursor_rule --out "$ART/overseer.v0.1.0.mdc" |
| 56 | run "1b. generate cli_runbook @ v0.1.0" \ |
| 57 | node cli/index.mjs flow project "$FLOW" --harness cli_runbook --out "$ART/overseer.AGENTS.v0.1.0.md" |
| 58 | |
| 59 | # baseline --check is clean (artifact matches a fresh render of the same version) |
| 60 | run "1c. --check baseline cli_runbook (expect drift=false, exit 0)" \ |
| 61 | node cli/index.mjs flow project "$FLOW" --harness cli_runbook --out "$ART/overseer.AGENTS.v0.1.0.md" --check |
| 62 | |
| 63 | # --- Stage B: add canonical v0.2.0 (one tightened flow.summary + version bump) ------------- |
| 64 | # NOTE: the canonical change is at the FLOW level (summary). The 7A-10b store keys step bodies by |
| 65 | # step_id only (not (step_id, version)), so a step-field change cannot diverge across versions in a |
| 66 | # single store — see docs/evidence/7A-12/README.md "Store finding". A flow-level change proves |
| 67 | # anti-drift cleanly through both harnesses without depending on that gap. |
| 68 | node -e "import('./lib/flow/flow-store.mjs').then(m=>{const r=m.seedStarterFlows(process.env.KNOWTATION_DATA_DIR,'default',{starterDir:'$V2'});console.log('seed v2',JSON.stringify(r));})" | tee -a "$TRANSCRIPT" |
| 69 | |
| 70 | # (2) Regenerate at latest (now v0.2.0) and prove the diff carries ONLY the canonical change |
| 71 | run "2a. regenerate cursor_rule @ latest (v0.2.0)" \ |
| 72 | node cli/index.mjs flow project "$FLOW" --harness cursor_rule --out "$ART/overseer.v0.2.0.mdc" |
| 73 | run "2b. regenerate cli_runbook @ latest (v0.2.0)" \ |
| 74 | node cli/index.mjs flow project "$FLOW" --harness cli_runbook --out "$ART/overseer.AGENTS.v0.2.0.md" |
| 75 | |
| 76 | log "" |
| 77 | log "### 2c. diff v0.1.0 -> v0.2.0 (cursor_rule) — expect only marker version + verification line" |
| 78 | diff -u "$ART/overseer.v0.1.0.mdc" "$ART/overseer.v0.2.0.mdc" | tee "$ART/overseer.cursor.v1-to-v2.diff" | tee -a "$TRANSCRIPT" |
| 79 | log "[diff captured: $ART/overseer.cursor.v1-to-v2.diff]" |
| 80 | |
| 81 | log "" |
| 82 | log "### 2d. diff v0.1.0 -> v0.2.0 (cli_runbook) — expect only marker version + verification line" |
| 83 | diff -u "$ART/overseer.AGENTS.v0.1.0.md" "$ART/overseer.AGENTS.v0.2.0.md" | tee "$ART/overseer.runbook.v1-to-v2.diff" | tee -a "$TRANSCRIPT" |
| 84 | log "[diff captured: $ART/overseer.runbook.v1-to-v2.diff]" |
| 85 | |
| 86 | # (3) Delete loses nothing: remove the v0.2.0 artifact, regenerate, prove byte-identical |
| 87 | cp "$ART/overseer.v0.2.0.mdc" "$ART/.overseer.v0.2.0.mdc.keep" |
| 88 | rm -f "$ART/overseer.v0.2.0.mdc" |
| 89 | run "3a. regenerate deleted cursor_rule @ v0.2.0" \ |
| 90 | node cli/index.mjs flow project "$FLOW" --harness cursor_rule --out "$ART/overseer.v0.2.0.mdc" |
| 91 | log "" |
| 92 | log "### 3b. byte-identical after delete+regenerate (expect no output / identical)" |
| 93 | if diff "$ART/.overseer.v0.2.0.mdc.keep" "$ART/overseer.v0.2.0.mdc" >>"$TRANSCRIPT" 2>&1; then |
| 94 | log "IDENTICAL: regenerated artifact == pre-delete artifact (lossless)" |
| 95 | else |
| 96 | log "MISMATCH: regeneration was not byte-identical" |
| 97 | fi |
| 98 | rm -f "$ART/.overseer.v0.2.0.mdc.keep" |
| 99 | |
| 100 | # (4) Hand-edit is caught: scribble on the artifact, --check must report drift + exit non-zero |
| 101 | cp "$ART/overseer.AGENTS.v0.2.0.md" "$ART/overseer.AGENTS.handedited.md" |
| 102 | printf '\n<!-- hand-scribbled note that is NOT in canonical -->\n' >> "$ART/overseer.AGENTS.handedited.md" |
| 103 | run "4. --check hand-edited cli_runbook (expect drift=true edited, exit 1)" \ |
| 104 | node cli/index.mjs flow project "$FLOW" --harness cli_runbook --out "$ART/overseer.AGENTS.handedited.md" --check |
| 105 | |
| 106 | # (5) Staleness surfaces: pin the older version against the lagging artifact |
| 107 | run "5. --check pinned v0.1.0 vs latest v0.2.0 (expect stale=true, exit 1)" \ |
| 108 | node cli/index.mjs flow project "$FLOW" --harness cli_runbook --version 0.1.0 --out "$ART/overseer.AGENTS.v0.1.0.md" --check |
| 109 | |
| 110 | # (6) Fidelity honesty across harnesses (machine-readable envelope) |
| 111 | run "6a. cursor_rule fidelity (expect when_not_to_run dropped)" \ |
| 112 | node cli/index.mjs flow project "$FLOW" --harness cursor_rule --json |
| 113 | run "6b. cli_runbook fidelity (expect when_not_to_run expressed, not dropped)" \ |
| 114 | node cli/index.mjs flow project "$FLOW" --harness cli_runbook --json |
| 115 | |
| 116 | log "" |
| 117 | log "=== demo complete — artifacts + diffs + transcript under $ART ===" |
| 118 | rm -rf "$STORE_ROOT" |
File History
1 commit
sha256:8915fe406161f95c1681f9469375e7bae5b28c884f00bedbdef65e4b0cd0738d
docs(flow): commit FLOW-V0-SPEC.md hygiene for 7A-INT merge
Human
17 hours ago