From 827a3e56dc5569689ae6820a8cdd611a590c5c0d Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 11:03:36 -0700 Subject: [PATCH 01/20] docs: refresh primer and LEARNINGS after PR #49 merge Records PR #49 as merged, updates the git-log block, and captures two LEARNINGS entries from the docguard-generalization session: the worktree-isolation guard's broader non-git trigger surface (#17), and verifying subagent commit claims independently rather than trusting the status string (#18). --- .session-continuity/LEARNINGS.md | 38 +++++++++++++++++++++++++++ .session-continuity/SESSION_PRIMER.md | 27 ++++++++++++++++--- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/.session-continuity/LEARNINGS.md b/.session-continuity/LEARNINGS.md index d25c417..8b47f6c 100644 --- a/.session-continuity/LEARNINGS.md +++ b/.session-continuity/LEARNINGS.md @@ -16,6 +16,7 @@ within each group. each time it appends a new entry. --> +- A subagent reported commit `9b2f504` in repo A; `git rev-parse --verify` in… — #18 - After GitHub squash-merged PR #20, `git merge --ff-only — #15 - Clean-machine acceptance test for v0.4.0. `/session-continuity:primer` ran init mode cleanly, asked for… — #4 - Denied again, on the same file, despite the escape hatch already being… — #13 @@ -27,6 +28,7 @@ within each group. - Real invocation of `/session-continuity:primer` after installing the change failed every one of… — #11 - The Bash call is refused outright: "This session is isolated in the… — #8 - The first v0.2.0 release fired the workflow, created the GitHub Release, but… — #2 +- The same "too complex to verify that it stays inside the worktree"… — #17 - The self-gate check returned rc=0 (allowed) — but via the escape hatch… — #7 - The `/session-continuity:end-session` smoke test had two staged files (primer + `src/foo.js`). The… — #3 - The smoke test written for exactly this case (`Smoke: N/A deferred, this… — #16 @@ -37,6 +39,28 @@ within each group. ## Claude Code plugin mechanics +### 17. Worktree-isolation guard blocks any "too complex" command, not just `git -C` or compound git chains +Slug: worktree-guard-blocks-non-git-commands +Trigger: Bash /<\(|<<['"]?[A-Za-z]/ +Occurrence count: 3 of 3 +Invariant: Inside a worktree-isolated session, every Bash call is one +plain single-statement command targeting the current directory — no +`&&`/`;`/multi-line chains, no `<(...)` process substitution, no +heredocs, and no `git -C` — regardless of whether git is involved at +all. When multiple statements are genuinely needed in sequence, write +them to a script file (`Write` + `bash /tmp/script.sh`) instead of +one compound Bash call. + +**The trap.** [[worktree-compound-commands-blocked]] already covers `git -C` and `&&`/`;` chains. It's easy to assume the guard is git-specific and keep using `diff <(...) <(...)`, multi-line heredocs, or a `source`+function-call block for pure-bash work with zero git involvement. + +**Symptom.** The same "too complex to verify that it stays inside the worktree" refusal fires on plain `diff`/`sed`/`source` commands using process substitution or heredocs — no `git` anywhere in the command. Recurred 8 times over 36 minutes in one session. + +**Fix.** Split into plain single-statement commands (one command per Bash call, no `<(...)`, no heredoc, no `&&`/`;`), or when the logic genuinely needs several statements in sequence, write it to a script file with `Write` and run `bash /tmp/script.sh` as a single plain command. + +**Diagnostic signal** *(optional)*. Bash error text containing "too complex to verify that it stays inside the worktree" on a command with no `git` in it at all. + +--- + ### 11. `$CLAUDE_PLUGIN_ROOT` inside a bash fence in a skill/command file is never resolved — only the braced `${CLAUDE_PLUGIN_ROOT}` form is Slug: plugin-root-brace-required Trigger: Write|Edit /\$CLAUDE_PLUGIN_ROOT\// @@ -318,6 +342,20 @@ parsed structure, never on a substring of serialized output. ## Git / release mechanics +### 18. A subagent's "DONE, commit ``" can be a real commit — in the wrong repo +Slug: verify-subagent-commit-independently +Trigger: * + +**The trap.** When orchestrating subagents across two related git repos/worktrees in one session, it's tempting to trust a resumed subagent's self-report of a commit hash once it "looks real" (right format, plausible message) — especially after a first check already caught it lying once, making a second check feel redundant. + +**Symptom.** A subagent reported commit `9b2f504` in repo A; `git rev-parse --verify` in repo A correctly said it didn't exist, so the report was flagged as fabricated. Two tasks later, the *exact same hash* turned up as the real, current `HEAD` of a completely different repo (repo B) — the subagent's `git commit` had actually succeeded, just against the wrong repo, most likely due to a cwd reset across a resumed-agent tool call. The "fabricated" commit was real; it just wasn't where anyone was looking. + +**Fix.** Independently verify every subagent-claimed commit with `git rev-parse --show-toplevel` (confirm the repo) plus `git rev-parse --verify ` and `git log --oneline`/`git status --porcelain` (confirm the commit and a clean tree) — in every worktree that could plausibly have received it, not just the one it was supposed to go to. A "not found here" result answers only "not here," never "doesn't exist." + +**Diagnostic signal** *(optional)*. A claimed hash that fails `git rev-parse --verify` in the expected repo — before concluding "fabricated," check whether it exists as real `HEAD` in any other repo/worktree this session touched. + +--- + ### 15. Squash-merging a branch descended from an unpushed local commit orphans that commit — and any tag pointing at it Trigger: Bash /gh pr merge.*--squash/ Slug: squash-merge-orphans-unpushed-tag diff --git a/.session-continuity/SESSION_PRIMER.md b/.session-continuity/SESSION_PRIMER.md index e31683f..66c9620 100644 --- a/.session-continuity/SESSION_PRIMER.md +++ b/.session-continuity/SESSION_PRIMER.md @@ -20,6 +20,24 @@ rarely. ## Current state +- **Backlog #38 (docguard generalization) — this repo's side merged, the + actual mechanism not yet activated.** PR + https://github.com/talgolan/session-continuity/pull/49 (merged + 2026-09-08) updates this repo's design doc + (`meta/superpowers/recommendations/docguard-design-sketch.md`) to record + the mechanism as built. The actual code — a hand-rolled `.docguard.yml` + parser and `~/.githooks/post-merge` wiring — lives on branch + `docguard-generalization` in `~/.githooks`, a *separate* git repo + (discovered mid-session: `~/.githooks` is not its own repo, it's a + subdirectory of a personal dotfiles repo rooted at `$HOME` with a + blanket exclude + per-file force-add; `post-merge` had never been + tracked there before this work). That branch is intentionally kept + unmerged: merging would make git try to check out a newly-tracked + `post-merge` over the path where the live, still-untracked hook sits, + which needs a deliberate reconciliation step first. Issue #38 stays open + until that lands. Plan: + `meta/superpowers/plans/2026-09-08-docguard-generalization.md` (this + repo, untracked by design — a working record, not shipped content). - **v0.29.0 released** — GitHub Issues labeled `backlog` replace `.session-continuity/BACKLOG.md`. Merged to `main` via PR #47 (`999e1f2`), tag `v0.29.0`, release https://github.com/talgolan/session-continuity/releases/tag/v0.29.0. Identity is `#N`; LEARNINGS stays a local file. This repo's live items are issues #35–#45. - **v0.27.1 — gate-escape self-condemnation hazard fixed, merged to `main` via PR #33 (`dd84ee7`) and released (tag `v0.27.1`, bumped in `c00cf17`).** @@ -621,10 +639,11 @@ rarely. **Current `git log --oneline -5` (primary branch):** ``` -999e1f2 Merge pull request #47 from talgolan/feat/github-issues-backlog -dc9c788 feat: replace BACKLOG.md with GitHub Issues labeled backlog (v0.29.0) -f79eb10 chore: bump to 0.28.0 — shared mechanics library (perf-log mark/since, primer-status.sh) -6b70556 Merge pull request #34 from talgolan/feat/shared-mechanics-library +c9ecacc Merge pull request #49 from talgolan/worktree-docguard-generalization +d36d472 docs: don't claim GitHub issue #38 is closed until it actually is +8b11c46 docs: mark docguard generalization implemented, correct hard-block assumption +db8ec26 Merge pull request #48 from talgolan/fix/ghe-backlog-origin-check +16f8d06 fix: recognize GitHub Enterprise Server origins for the backlog queue ff6b8c8 test: bump stale count-entries-smoke pins to real BACKLOG/LEARNINGS counts (16/18) ``` From a07ace56ed3bde9075d98b1aab8e5570c82b54b9 Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 11:40:40 -0700 Subject: [PATCH 02/20] fix: agent-active.sh fallback no longer sums full wall-clock span The fallback's idle-gap exclusion checked $a.subtype=="turn_duration", which can never be true inside a branch already guarded on zero such records in range -- so the exclusion was dead code and the fallback degraded to the raw first-to-last timestamp span (verified: 2218.479s transcript span vs. corrected 1778.000s). Fixed by identifying the real turn-boundary signal instead: a genuine human-typed prompt (message.content is plain text, isMeta != true), not bare type=="user" -- most type=="user" records are tool_result blocks whose preceding gap is agent-active tool-execution time, not idle. Fixes #39 Co-Authored-By: Claude Sonnet 5 --- hooks/lib/agent-active.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/hooks/lib/agent-active.sh b/hooks/lib/agent-active.sh index 972855a..fae3ca6 100755 --- a/hooks/lib/agent-active.sh +++ b/hooks/lib/agent-active.sh @@ -17,6 +17,16 @@ # spec's Change 2). Falls back to a timestamp turn-boundary walk (weaker: # infers boundaries from record adjacency rather than reading an explicit # field) only when zero turn_duration records exist in range at all. +# +# Fallback boundary signal: a genuine human-typed prompt, not bare +# type=="user" -- most type=="user" records are tool_result blocks (the +# Messages API forces tool results onto a "user" turn) and the gap before +# one of those is agent-active tool-execution time, not idle. Only a real +# human prompt (message.content is plain text, isMeta != true) marks the +# end of an idle gap. See is_human_prompt below; conflating the two used +# to make the fallback sum the entire wall-clock span instead of excluding +# idle time (bug: the exclusion checked $a.subtype=="turn_duration", which +# can never be true inside a branch already guarded on zero such records). set -u @@ -29,6 +39,15 @@ command -v jq >/dev/null 2>&1 || exit 0 RESULT="$(jq -s --argjson start "$START_EPOCH" ' def to_epoch: gsub("\\.[0-9]+Z$"; "Z") | fromdateiso8601; + # A genuine human-typed prompt, as opposed to a tool_result record (also + # type=="user" in this schema) or a synthetic isMeta injection. Only the + # arrival of a real human prompt marks the end of an idle (user-composing) + # gap -- tool_result gaps are agent-active time and must stay counted. + def is_human_prompt: + .type=="user" and (.isMeta != true) and ( + (.message.content | type) == "string" + or ((.message.content | type) == "array" and (.message.content | all(.type=="text"))) + ); (map(select(.timestamp != null and (.timestamp | to_epoch) >= $start))) as $in_range | ($in_range | map(select(.type=="system" and .subtype=="turn_duration"))) as $turns | if ($turns | length) > 0 then @@ -39,7 +58,7 @@ RESULT="$(jq -s --argjson start "$START_EPOCH" ' . as $acc | $sorted[$i] as $a | $sorted[$i+1] as $b - | if ($a.type=="system" and $a.subtype=="turn_duration") then $acc + | if ($b | is_human_prompt) then $acc else $acc + (($b.timestamp | to_epoch) - ($a.timestamp | to_epoch)) end )) From 93c433f10f55af28bc63d5d15e4c9a06f2ba84a5 Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 12:19:36 -0700 Subject: [PATCH 03/20] fix: overlap() dedupe before Jaccard so it stops over-merging retry-bursts Numerator counted a title's own repeated words as multiplicity while the denominator was already deduped, so a repeated word shared with an unrelated candidate's title (often the "re-run N times..." boilerplate) could inflate the score past the 0.7 dedup threshold and drop a genuinely distinct retry-burst. Dedupe both word lists before intersecting. Closes #40. Co-Authored-By: Claude Sonnet 5 --- .session-continuity/SESSION_PRIMER.md | 17 ++++++++++++++ hooks/lib/candidate-extract.jq | 4 ++-- .../2026-09-01-candidate-extract-smoke.zsh | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/.session-continuity/SESSION_PRIMER.md b/.session-continuity/SESSION_PRIMER.md index 66c9620..abeb74f 100644 --- a/.session-continuity/SESSION_PRIMER.md +++ b/.session-continuity/SESSION_PRIMER.md @@ -20,6 +20,23 @@ rarely. ## Current state +- **Closes backlog #40: `overlap()`'s asymmetric Jaccard in + `hooks/lib/candidate-extract.jq` over-merged distinct retry-bursts.** + The numerator (`$wa - ($wa - $wb)`) counted `$wa`'s own word + *multiplicity*, while the denominator (`$u`) was deduped — a repeated + word inside one candidate's title (e.g. a command whose args happen to + contain "file", which also sits in the "— re-run N times with M file + edits in between." boilerplate) inflated that title's similarity score + against an unrelated candidate enough to cross the 0.7 dedup threshold + and get it wrongly dropped. Fixed by deduping `$wa`/`$wb` before + intersecting (`unique` added at both `title_words` call sites), making + the ratio a real Jaccard index and direction-symmetric. New regression + case in `meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh` + (two genuinely distinct retry-bursts — one command's args repeat "file" + — must both survive dedup); verified end-to-end pre-fix collapse (1 + candidate) vs. post-fix (2) via a real transcript fixture through + `candidate-extract.sh`, not just the isolated `overlap()` filter. Full + suite 31/31 green. - **Backlog #38 (docguard generalization) — this repo's side merged, the actual mechanism not yet activated.** PR https://github.com/talgolan/session-continuity/pull/49 (merged diff --git a/hooks/lib/candidate-extract.jq b/hooks/lib/candidate-extract.jq index c358f7a..6b7bb42 100644 --- a/hooks/lib/candidate-extract.jq +++ b/hooks/lib/candidate-extract.jq @@ -99,8 +99,8 @@ def title_words: | map(select(length > 0)); def overlap($ta; $tb): - ($ta | title_words) as $wa - | ($tb | title_words) as $wb + ($ta | title_words | unique) as $wa + | ($tb | title_words | unique) as $wb | ($wa + $wb | unique) as $u | if ($u | length) == 0 then 0 else (($wa - ($wa - $wb)) | length) / ($u | length) diff --git a/meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh b/meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh index d41dda2..a802dd7 100644 --- a/meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh +++ b/meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh @@ -117,6 +117,28 @@ n="$(print -r -- "$out" | jq '[.candidates[] | select(.heuristic=="retry-burst") || bad "expected 1 merged retry-burst, got $n: $out" rm -f "$fam_f" +# Regression: overlap() must dedupe words before intersecting, not just before +# unioning. A command whose own text repeats a word that also happens to sit +# in the "— re-run N times with M file edits in between." boilerplate (here, +# "file") must not inflate that title's similarity score against an unrelated +# burst enough to get it wrongly dropped as a duplicate. +jaccard_f="$(mktemp)" +{ + mk_bash_call "2026-09-08T00:00:00.000Z" "j1" "pytest tests/file_file_file_file_test.py" + mk_edit "2026-09-08T00:00:30.000Z" "je1" + mk_bash_call "2026-09-08T00:01:00.000Z" "j2" "pytest tests/file_file_file_file_test.py" + mk_bash_call "2026-09-08T00:02:00.000Z" "j3" "pytest tests/file_file_file_file_test.py" + mk_bash_call "2026-09-08T00:03:00.000Z" "j4" "curl -s https://example.com/api" + mk_edit "2026-09-08T00:03:30.000Z" "je2" + mk_bash_call "2026-09-08T00:04:00.000Z" "j5" "curl -s https://example.com/api" + mk_bash_call "2026-09-08T00:05:00.000Z" "j6" "curl -s https://example.com/api" +} > "$jaccard_f" +out="$(bash "$lib/candidate-extract.sh" "$jaccard_f")" +n="$(print -r -- "$out" | jq '[.candidates[] | select(.heuristic=="retry-burst")] | length')" +[[ "$n" -eq 2 ]] && ok "overlap(): a repeated word inside one title does not over-merge distinct retry-bursts" \ + || bad "expected 2 distinct retry-bursts, overlap() collapsed them to $n: $out" +rm -f "$jaccard_f" + # --- Heuristic B: revert / reset (needs a real tracked file) --------------- repo_dir="$(gt_make_repo)" From 858415add90260f386bf5cd2b86822f64b2bdd74 Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 13:14:24 -0700 Subject: [PATCH 04/20] feat: add checklist-assemble.sh, scripting end-session Step 3's row assembly --- hooks/lib/checklist-assemble.sh | 173 +++++++++++++++++ .../2026-09-08-checklist-assemble-smoke.zsh | 180 ++++++++++++++++++ 2 files changed, 353 insertions(+) create mode 100755 hooks/lib/checklist-assemble.sh create mode 100755 meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh diff --git a/hooks/lib/checklist-assemble.sh b/hooks/lib/checklist-assemble.sh new file mode 100755 index 0000000..a2de72d --- /dev/null +++ b/hooks/lib/checklist-assemble.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/checklist-assemble.sh — Step 3 checklist renderer for +# /session-continuity:end-session (session-continuity plugin). +# +# Usage: checklist-assemble.sh [] +# Reads one JSON object on stdin (see +# meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md +# Task 1 for the full contract) and prints the finished eight-row checklist, +# suggested-commit block, and terminal sign-off line on stdout. Always exits +# 0: a rendering failure must degrade to SC-FALLBACK, never abort the ritual. +# +# is read only when the input's backlog_mode=="normal". +# Each line is tag\tverdict\tcitation, one per open backlog item still +# subject to Step 1's overlap gate. A missing/unreadable path in that mode +# degrades to zero tracked items rather than falling back — an empty +# backlog is a valid state, distinct from malformed input. + +set -uo pipefail + +INPUT="$(cat)" +TSV_PATH="${1:-}" + +fallback() { # + printf 'SC-FALLBACK: manual — %s\n' "$1" + exit 0 +} + +command -v jq >/dev/null 2>&1 || fallback "jq is not installed." + +if ! printf '%s' "$INPUT" | jq -e 'type == "object"' >/dev/null 2>&1; then + fallback "malformed checklist JSON." +fi + +for key in staged unstaged untracked branch primer learnings backlog_mode; do + if ! printf '%s' "$INPUT" | jq -e "has(\"$key\")" >/dev/null 2>&1; then + fallback "checklist JSON missing required key '$key'." + fi +done + +# --- backlog TSV -> a JSON array jq can fold in ------------------------------ +BACKLOG_MODE="$(printf '%s' "$INPUT" | jq -r '.backlog_mode')" +case "$BACKLOG_MODE" in + normal|none|unavailable|not-migrated|fast-path) ;; + *) fallback "unrecognized backlog_mode '$BACKLOG_MODE'." ;; +esac + +BACKLOG_ITEMS_JSON='[]' +if [[ "$BACKLOG_MODE" == "normal" && -n "$TSV_PATH" && -r "$TSV_PATH" ]]; then + # jq's own JSON string encoding handles quotes, backslashes, and control + # characters correctly — no hand-rolled escaping. Split each line on tab; + # a citation containing a literal tab (columns 4+) is rejoined with "\t" + # rather than truncated. + BACKLOG_ITEMS_JSON="$( + jq -R -s ' + split("\n") | map(select(length > 0)) | map(split("\t")) | + map(select(length >= 3)) | + map({tag: .[0], verdict: .[1], citation: (.[2:] | join("\t"))}) + ' "$TSV_PATH" 2>/dev/null + )" + if ! printf '%s' "$BACKLOG_ITEMS_JSON" | jq -e . >/dev/null 2>&1; then + BACKLOG_ITEMS_JSON='[]' + fi +fi + +OUT="$( + printf '%s' "$INPUT" | jq -r --argjson items "$BACKLOG_ITEMS_JSON" ' + # --- row 1: primer ------------------------------------------------------- + def primer_row: + if .primer == "refreshed" then "✓ Primer refreshed and staged" + elif .primer == "closed" then "✓ Primer updated (outstanding item(s) closed)" + else "✓ Primer already current (no-op)" end; + + # --- row 2: learnings ----------------------------------------------------- + def learnings_row: + (.learnings // []) as $l + | if ($l | length) == 0 then "✓ No new learnings" + else + ($l | length) as $n + | (if $n == 1 then "entry" else "entries" end) as $noun + | ([$l[] | "#" + (.number|tostring) + ", \"" + .title + "\""] | join(", ")) as $cited + | "✓ " + ($n|tostring) + " LEARNINGS " + $noun + " captured (" + $cited + ")" + end; + + # --- row 3: backlog --------------------------------------------------------- + def backlog_row: + if .backlog_mode == "none" then {marker:"✓", text:"Backlog: none tracked"} + elif .backlog_mode == "unavailable" then {marker:"✓", text:"Backlog: GitHub queue unavailable — run /session-continuity:doctor"} + elif .backlog_mode == "not-migrated" then {marker:"✓", text:"Backlog: not migrated — run /session-continuity:primer"} + elif .backlog_mode == "fast-path" then {marker:"✓", text:"Backlog: " + (.backlog_fastpath_count|tostring) + " tracked — not re-verified this session (no repo changes since last close-out)"} + else + ($items) as $it + | ($it | length) as $n + | ($it | map(select(.verdict=="appears-DONE"))) as $done + | ($it | map(select(.verdict=="still-open"))) as $open + | ($it | map(select(.verdict=="manual"))) as $man + | ([ + (if ($done|length) > 0 then ($done|length|tostring) + " appears-DONE (" + ([$done[] | .tag + ", \"" + .citation + "\""] | join(", ")) + ")" else empty end), + (if ($open|length) > 0 then ($open|length|tostring) + " still-open (" + ([$open[] | .tag] | join(", ")) + ")" else empty end), + (if ($man|length) > 0 then ($man|length|tostring) + " manual (" + ([$man[] | .tag] | join(", ")) + ")" else empty end) + ] | join(", ")) as $clauses + | {marker: (if ($done|length) > 0 then "⚠️" else "✓" end), + text: "Backlog: " + ($n|tostring) + " tracked" + (if $n > 0 then " — " + $clauses else "" end)} + end; + + # --- rows 4-6: file lists --------------------------------------------------- + def staged_row: + (.staged // []) as $s + | if ($s|length) == 0 then {marker:"✓", text:"Nothing staged"} + else {marker:"✓", text:"Staged: " + ($s|join(", "))} end; + + def unstaged_row: + (.unstaged // []) as $u + | if ($u|length) == 0 then {marker:"✓", text:"No unstaged modifications"} + else {marker:"⚠️", text:"Unstaged: " + ($u|join(", "))} end; + + def untracked_row: + (.untracked // []) as $t + | if ($t|length) == 0 then {marker:"✓", text:"No untracked files"} + else {marker:"⚠️", text:($t|length|tostring) + " untracked: " + ($t|join(", ")) + " — ignore, add, or delete?"} end; + + # --- row 7: unpushed commits ------------------------------------------------- + def unpushed_row: + if .detached == true then + {marker:"⚠️", text:"detached HEAD at " + (.short_sha // "?")} + elif .upstream == null then + {marker:"⚠️", text:"branch `" + .branch + "` has no upstream — set one with `git push -u origin " + .branch + "`"} + elif (.ahead // 0) == 0 then + {marker:"✓", text:"Up to date with " + .upstream} + else + {marker:"⚠️", text:"Branch `" + .branch + "` is " + (.ahead|tostring) + " commits ahead of origin — push before closing?"} + end; + + # --- row 8: suggested commit -------------------------------------------------- + def suggested_row: + (.staged // []) as $s + | if ($s|length) == 0 then null + else + (if ([$s[] | startswith(".session-continuity/")] | all) then "docs: update session continuity" + elif .commit_subject != null then .commit_subject + else "chore: update " + ($s|length|tostring) + " file(s)" end) as $subject + | "→ Suggested:\n```\ngit commit -m \"" + $subject + "\"\n```" + end; + + (primer_row) as $r1 + | (learnings_row) as $r2 + | (backlog_row) as $r3 + | (staged_row) as $r4 + | (unstaged_row) as $r5 + | (untracked_row) as $r6 + | (unpushed_row) as $r7 + | (suggested_row) as $r8 + | [$r1, $r2, ($r3.marker + " " + $r3.text), ($r4.marker + " " + $r4.text), + ($r5.marker + " " + $r5.text), ($r6.marker + " " + $r6.text), + ($r7.marker + " " + $r7.text)] as $rows + | ($rows | map(test("⚠️")) | any) as $any_warn + | ($rows + (if $r8 != null then [$r8] else [] end)) as $all_lines + | ($all_lines | join("\n")) + + "\n\n" + + (if $any_warn then + "✅ Session complete. Safe to close. (Warnings above are advisory — review before closing if relevant.)" + else + "✅ Session complete. Safe to close." + end) + ' 2>/dev/null +)" +JQ_STATUS=$? + +if [[ "$JQ_STATUS" -ne 0 || -z "$OUT" ]]; then + fallback "checklist JSON did not match the expected shape." +fi + +printf '%s\n' "$OUT" diff --git a/meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh b/meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh new file mode 100755 index 0000000..a9a8573 --- /dev/null +++ b/meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh @@ -0,0 +1,180 @@ +#!/usr/bin/env zsh +# checklist-assemble.sh smoke test. Hermetic: fixture JSON + a throwaway +# TSV file, no real git state. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +tool="$lib/checklist-assemble.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +run() { print -rn -- "$1" | bash "$tool" "${2:-}"; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +base_json() { + # Minimal valid document: nothing staged/unstaged/untracked, primer + # current, no learnings, no backlog tracked, upstream clean. + cat <<'JSON' +{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false, + "short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current", + "learnings":[],"backlog_mode":"none","backlog_fastpath_count":null, + "commit_subject":null} +JSON +} + +# --- malformed JSON must not crash, must fall back ------------------------- +out="$(run 'not json at all')" +[[ "$out" == SC-FALLBACK:* ]] && ok "malformed JSON -> SC-FALLBACK" \ + || bad "expected SC-FALLBACK, got: $out" + +# --- missing required key must not crash ------------------------------------ +out="$(run '{"staged":[]}')" +[[ "$out" == SC-FALLBACK:* ]] && ok "missing required keys -> SC-FALLBACK, no crash" \ + || bad "expected SC-FALLBACK, got: $out" + +# --- fully clean run: every row ✓, no suggested-commit row, clean sign-off -- +out="$(run "$(base_json)")" +expected="✓ Primer already current (no-op) +✓ No new learnings +✓ Backlog: none tracked +✓ Nothing staged +✓ No unstaged modifications +✓ No untracked files +✓ Up to date with origin/main + +✅ Session complete. Safe to close." +[[ "$out" == "$expected" ]] && ok "fully clean run renders all-✓ checklist, no suggested-commit row, clean sign-off" \ + || bad "got:\n$out" + +# --- new learnings row: singular vs plural ---------------------------------- +one_learning='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[{"number":7,"title":"awk range collapse"}],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$one_learning")" +[[ "$out" == *'✓ 1 LEARNINGS entry captured (#7, "awk range collapse")'* ]] \ + && ok "one learning -> singular 'entry'" \ + || bad "got:\n$out" + +two_learnings='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[{"number":7,"title":"A"},{"number":8,"title":"B"}],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$two_learnings")" +[[ "$out" == *'✓ 2 LEARNINGS entries captured (#7, "A", #8, "B")'* ]] \ + && ok "two learnings -> plural 'entries', both cited" \ + || bad "got:\n$out" + +# --- backlog: fast-path mode ------------------------------------------------- +fastpath='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"fast-path","backlog_fastpath_count":5,"commit_subject":null}' +out="$(run "$fastpath")" +[[ "$out" == *'✓ Backlog: 5 tracked — not re-verified this session (no repo changes since last close-out)'* ]] \ + && ok "fast-path backlog mode renders the standing-count line" \ + || bad "got:\n$out" + +# --- backlog: unavailable / not-migrated modes ------------------------------- +unavail='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"unavailable","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$unavail")" +[[ "$out" == *'✓ Backlog: GitHub queue unavailable — run /session-continuity:doctor'* ]] \ + && ok "unavailable backlog mode renders the doctor pointer" \ + || bad "got:\n$out" + +notmig='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"not-migrated","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$notmig")" +[[ "$out" == *'✓ Backlog: not migrated — run /session-continuity:primer'* ]] \ + && ok "not-migrated backlog mode renders the primer pointer" \ + || bad "got:\n$out" + +# --- backlog: normal mode, mixed verdicts, TSV-driven ------------------------ +tsv="$work/backlog.tsv" +cat <<'TSV' > "$tsv" +#4 appears-DONE found test/end_to_end.bats -> 0 hits before, now present +#3 still-open no *.bats and no test/ dir -> item still open +#5 manual not auto-verifiable +#6 manual no related commits since last refresh -- not re-checked this session +TSV +normal='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"normal","backlog_fastpath_count":null,"commit_subject":null}' +out="$(print -rn -- "$normal" | bash "$tool" "$tsv")" +[[ "$out" == *'⚠️ Backlog: 4 tracked — 1 appears-DONE (#4, "found test/end_to_end.bats -> 0 hits before, now present"), 1 still-open (#3), 2 manual (#5, #6)'* ]] \ + && ok "normal mode tallies all three verdicts, cites only appears-DONE, marks ⚠️" \ + || bad "got:\n$out" +[[ "$out" == *'(Warnings above are advisory'* ]] \ + && ok "any ⚠️ row flips the sign-off line to the advisory variant" \ + || bad "sign-off did not carry the warning suffix:\n$out" + +# --- backlog: normal mode, zero appears-DONE -> ✓, no advisory suffix ------- +cat <<'TSV' > "$tsv" +#3 still-open no *.bats and no test/ dir -> item still open +TSV +out="$(print -rn -- "$normal" | bash "$tool" "$tsv")" +[[ "$out" == *'✓ Backlog: 1 tracked — 1 still-open (#3)'* ]] \ + && ok "normal mode with zero appears-DONE marks ✓, omits the empty appears-DONE clause" \ + || bad "got:\n$out" + +# --- backlog: normal mode, missing TSV path degrades to zero items --------- +out="$(print -rn -- "$normal" | bash "$tool" "$work/does-not-exist.tsv")" +[[ "$out" == *'✓ Backlog: 0 tracked'* ]] \ + && ok "normal mode with an unreadable TSV path degrades to zero tracked, no crash" \ + || bad "got:\n$out" + +# --- backlog: normal mode, citation with embedded quote and backslash ------ +printf '#9\tappears-DONE\tfound "weird" path C:\\temp\\x -> present\n' > "$tsv" +out="$(print -rn -- "$normal" | bash "$tool" "$tsv")" +[[ "$out" == *'1 appears-DONE (#9, "found "weird" path C:\temp\x -> present")'* ]] \ + && ok "citation with embedded quote/backslash renders without breaking JSON parsing" \ + || bad "got:\n$out" + +# --- unrecognized backlog_mode -> SC-FALLBACK, no silent normal-mode fallthrough +bad_mode='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"Normal","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$bad_mode")" +[[ "$out" == SC-FALLBACK:* ]] \ + && ok "unrecognized backlog_mode -> SC-FALLBACK, not silently treated as normal" \ + || bad "got: $out" + +# --- staged/unstaged/untracked rows ------------------------------------------ +files='{"staged":["a.md","b.md"],"unstaged":["c.md"],"untracked":["d.tmp","e.tmp"],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$files")" +[[ "$out" == *'✓ Staged: a.md, b.md'* ]] && ok "staged row lists every file" || bad "got:\n$out" +[[ "$out" == *'⚠️ Unstaged: c.md'* ]] && ok "unstaged row warns and lists" || bad "got:\n$out" +[[ "$out" == *'⚠️ 2 untracked: d.tmp, e.tmp — ignore, add, or delete?'* ]] && ok "untracked row counts and lists" || bad "got:\n$out" + +# --- unpushed commits: all four branch states -------------------------------- +detached='{"staged":[],"unstaged":[],"untracked":[],"branch":"HEAD","detached":true,"short_sha":"deadbee","upstream":null,"ahead":null,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$detached")" +[[ "$out" == *'⚠️ detached HEAD at deadbee'* ]] && ok "detached HEAD row" || bad "got:\n$out" + +noupstream='{"staged":[],"unstaged":[],"untracked":[],"branch":"feature-x","detached":false,"short_sha":"abc1234","upstream":null,"ahead":null,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$noupstream")" +[[ "$out" == *'⚠️ branch `feature-x` has no upstream — set one with `git push -u origin feature-x`'* ]] \ + && ok "no-upstream row" || bad "got:\n$out" + +ahead='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":3,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$ahead")" +[[ "$out" == *'⚠️ Branch `main` is 3 commits ahead of origin — push before closing?'* ]] \ + && ok "ahead-of-origin row" || bad "got:\n$out" + +# --- suggested commit: omitted when nothing staged (already covered above) -- +# --- suggested commit: docs-only staged -> literal subject, ignores override - +docs_only='{"staged":[".session-continuity/SESSION_PRIMER.md",".session-continuity/LEARNINGS.md"],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"refreshed","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":"should be ignored"}' +out="$(run "$docs_only")" +[[ "$out" == *'git commit -m "docs: update session continuity"'* ]] \ + && ok "all-docs staged -> literal subject, ignores a supplied commit_subject" \ + || bad "got:\n$out" + +# --- suggested commit: mixed staged, caller-supplied subject used ----------- +mixed='{"staged":[".session-continuity/LEARNINGS.md","hooks/lib/foo.sh"],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"refreshed","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":"fix(ci): extract CHANGELOG section with proper awk range"}' +out="$(run "$mixed")" +[[ "$out" == *'git commit -m "fix(ci): extract CHANGELOG section with proper awk range"'* ]] \ + && ok "mixed staged with a supplied subject -> subject used verbatim" \ + || bad "got:\n$out" + +# --- suggested commit: mixed staged, no subject supplied -> mechanical fallback +mixed_nosubj='{"staged":[".session-continuity/LEARNINGS.md","hooks/lib/foo.sh"],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"refreshed","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$mixed_nosubj")" +[[ "$out" == *'git commit -m "chore: update 2 file(s)"'* ]] \ + && ok "mixed staged with no supplied subject -> mechanical N-file fallback, no invented theme" \ + || bad "got:\n$out" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) From 6b5b4fdb0cb90eb3d2dc367db3c2b4202cb56575 Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 13:29:01 -0700 Subject: [PATCH 05/20] fix: validate backlog_fastpath_count required for fast-path mode --- hooks/lib/checklist-assemble.sh | 7 +++++++ .../validation/2026-09-08-checklist-assemble-smoke.zsh | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/hooks/lib/checklist-assemble.sh b/hooks/lib/checklist-assemble.sh index a2de72d..68901b0 100755 --- a/hooks/lib/checklist-assemble.sh +++ b/hooks/lib/checklist-assemble.sh @@ -45,6 +45,13 @@ case "$BACKLOG_MODE" in *) fallback "unrecognized backlog_mode '$BACKLOG_MODE'." ;; esac +# --- fast-path mode requires backlog_fastpath_count (integer) ---------------- +if [[ "$BACKLOG_MODE" == "fast-path" ]]; then + if ! printf '%s' "$INPUT" | jq -e '.backlog_fastpath_count | type == "number"' >/dev/null 2>&1; then + fallback "checklist JSON missing required key 'backlog_fastpath_count' for backlog_mode fast-path." + fi +fi + BACKLOG_ITEMS_JSON='[]' if [[ "$BACKLOG_MODE" == "normal" && -n "$TSV_PATH" && -r "$TSV_PATH" ]]; then # jq's own JSON string encoding handles quotes, backslashes, and control diff --git a/meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh b/meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh index a9a8573..e770cd8 100755 --- a/meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh +++ b/meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh @@ -72,6 +72,13 @@ out="$(run "$fastpath")" && ok "fast-path backlog mode renders the standing-count line" \ || bad "got:\n$out" +# --- backlog: fast-path mode requires backlog_fastpath_count ---------------- +fastpath_null='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"fast-path","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$fastpath_null")" +[[ "$out" == SC-FALLBACK:* ]] \ + && ok "fast-path mode with null backlog_fastpath_count -> SC-FALLBACK" \ + || bad "got:\n$out" + # --- backlog: unavailable / not-migrated modes ------------------------------- unavail='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"unavailable","backlog_fastpath_count":null,"commit_subject":null}' out="$(run "$unavail")" From d2915e423513b716df7795d458e6fdda3dd9a40b Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 13:32:44 -0700 Subject: [PATCH 06/20] chore: gitignore the Step 3 backlog-verdict scratch file --- hooks/lib/perf-log.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/lib/perf-log.sh b/hooks/lib/perf-log.sh index 3cbe438..becfd80 100755 --- a/hooks/lib/perf-log.sh +++ b/hooks/lib/perf-log.sh @@ -54,7 +54,7 @@ write_record() { local GITIGNORE="$REPO_ROOT/.gitignore" touch "$GITIGNORE" 2>/dev/null local LINE - for LINE in ".session-continuity/performance.log" ".session-continuity/.gitignore-ensured"; do + for LINE in ".session-continuity/performance.log" ".session-continuity/.gitignore-ensured" ".session-continuity/.end-session-checklist.tsv"; do if ! grep -qxF "$LINE" "$GITIGNORE" 2>/dev/null; then printf '%s\n' "$LINE" >> "$GITIGNORE" 2>/dev/null fi From f7b4bb9240ba5328560a139bbf06b32f4ee45686 Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 13:35:54 -0700 Subject: [PATCH 07/20] feat: end-session Step 1 records backlog verdicts for the Step 3 checklist script --- commands/end-session.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/commands/end-session.md b/commands/end-session.md index fe30b62..238068f 100644 --- a/commands/end-session.md +++ b/commands/end-session.md @@ -40,11 +40,14 @@ _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") git status --porcelain git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md # git rev-parse HEAD +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" --count . # , "?" on failure _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-1-fast-path --duration="$_PERF_DURATION" ``` +`` feeds Step 3's `backlog_fastpath_count`. If it printed `?` (GitHub unavailable), use `backlog_mode="unavailable"` in Step 3 instead of `"fast-path"` — same GitHub-unavailable handling as the non-fast-path skip condition below. + If `git status --porcelain` is empty AND `` equals `HEAD` (no commits have landed since the primer was last touched), skip the rest of Step 1 entirely — no drift check, no backlog verification, @@ -158,6 +161,30 @@ auto-removed**. Removal of any item always requires explicit user confirmation. A verdict never mutates the primer on its own. +**Record every verdict for Step 3.** Once every open item has a verdict +(from the overlap gate, the batched classify/verify pass, or the +non-code default), write them all in **one Bash call**. There is no +in-shell list to loop over — the verdicts exist only in what you just +decided — so write one literal `printf` line per item by hand (not a +shell `for`/`while` loop): + +```bash +mkdir -p .session-continuity +: > .session-continuity/.end-session-checklist.tsv +printf '%s\t%s\t%s\n' "#4" "appears-DONE" "found test/end_to_end.bats -> 0 hits before, now present" >> .session-continuity/.end-session-checklist.tsv +printf '%s\t%s\t%s\n' "#3" "still-open" "no *.bats and no test/ dir -> item still open" >> .session-continuity/.end-session-checklist.tsv +# ... one such literal printf line per remaining open item, tag first (the +# #N identity, never the ephemeral 1..N list position), verdict second +# (still-open|appears-DONE|manual), citation third (the same evidence string +# already decided above — "not auto-verifiable" for non-code items, "no +# related commits since last refresh — not re-checked this session" for +# overlap-gated ones) ... +``` + +Skip this entirely when there were zero open items to classify (the file is +absent; Step 3 treats a missing path under `backlog_mode="normal"` as zero +tracked items — see `hooks/lib/checklist-assemble.sh`'s contract). + ### Drift check (silent — no user prompt) Read `.session-continuity/SESSION_PRIMER.md` and compare its `git log --oneline -5` block to the actual output of `git log --oneline -5` against the primary branch. Two outcomes: From a8b6b9a4e3e7f29766dec9a759ef5ab5d93df297 Mon Sep 17 00:00:00 2001 From: Tal Golan Date: Tue, 8 Sep 2026 13:41:25 -0700 Subject: [PATCH 08/20] refactor: end-session Step 3 renders the checklist via checklist-assemble.sh --- commands/end-session.md | 154 ++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 78 deletions(-) diff --git a/commands/end-session.md b/commands/end-session.md index 238068f..4d66275 100644 --- a/commands/end-session.md +++ b/commands/end-session.md @@ -435,94 +435,92 @@ Do not loop one-prompt-per-candidate. The batch is the unit. ## Step 3 — Final checklist -Run real git commands and emit a structured checklist. Every item must reflect actual repo state, not an assertion. - -### Gather the facts - -Run all six in **one Bash call** (one round trip, not six), timed: +One script call. Every row reflects actual repo state or a value you +decided in Step 1/Step 2 and pass through — never format or re-derive a row +by hand. + +### Gather the facts and render + +Run in **one Bash call**, timed. First, copy the Step 1 scratch TSV to a +location outside the repo and delete the in-repo copy — *before* any +git-status command runs, so the git commands below never see it (its path +can't be deleted-then-read, since `checklist-assemble.sh` needs to read it +after the git commands run; copying it out first is what makes both true +at once). Task 2's gitignore entry is the separate belt-and-suspenders case: +a ritual that crashes *before* this block ever runs leaves the file +in-repo, and only the gitignore entry (not this ordering) keeps it out of +a later `git ls-files --others`. Then run the seven git commands, then +build the JSON `checklist-assemble.sh` expects and pipe it through: ```bash _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") -git diff --cached --name-only # staged files -git diff --name-only # unstaged modifications -git ls-files --others --exclude-standard # untracked (ignoring .gitignore'd) -git rev-parse --abbrev-ref HEAD # current branch (or "HEAD" if detached) -git rev-parse --abbrev-ref @{u} 2>/dev/null # upstream branch, or empty if none -git rev-list --count @{u}..HEAD 2>/dev/null # unpushed commits, empty if no upstream +TSV_INREPO=".session-continuity/.end-session-checklist.tsv" +TSV="" +if [[ -r "$TSV_INREPO" ]]; then + TSV="$(mktemp)" + cp "$TSV_INREPO" "$TSV" + rm -f "$TSV_INREPO" +fi +BACKLOG_MODE="normal" # set to none|unavailable|not-migrated|fast-path per Step 1's skip conditions/fast path instead, when applicable +BACKLOG_FASTPATH_COUNT="null" # the fast path's , only when BACKLOG_MODE=fast-path + +STAGED_JSON="$(git diff --cached --name-only | jq -R -s 'split("\n") | map(select(length>0))')" +UNSTAGED_JSON="$(git diff --name-only | jq -R -s 'split("\n") | map(select(length>0))')" +UNTRACKED_JSON="$(git ls-files --others --exclude-standard | jq -R -s 'split("\n") | map(select(length>0))')" +BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo HEAD)" +if [[ "$BRANCH" == "HEAD" ]]; then DETACHED=true; else DETACHED=false; fi +SHORT_SHA="$(git rev-parse --short HEAD 2>/dev/null || echo '?')" +UPSTREAM="$(git rev-parse --abbrev-ref @{u} 2>/dev/null || true)" +if [[ -z "$UPSTREAM" ]]; then UPSTREAM_JSON="null"; AHEAD_JSON="null"; else + UPSTREAM_JSON="$(printf '%s' "$UPSTREAM" | jq -R .)" + AHEAD="$(git rev-list --count @{u}..HEAD 2>/dev/null || echo 0)" + AHEAD_JSON="$AHEAD" +fi + +# PRIMER, LEARNINGS_JSON, COMMIT_SUBJECT_JSON: set these three from what +# Step 1/Step 2 actually did this invocation — see the field notes below. +PRIMER="current" # "refreshed" | "closed" | "current" +LEARNINGS_JSON="[]" # e.g. '[{"number":7,"title":"..."}]' from Step 2's captures +COMMIT_SUBJECT_JSON="null" # a quoted JSON string, or "null", per the field note below + +JSON_TMP="$(mktemp)" +jq -n \ + --argjson staged "$STAGED_JSON" --argjson unstaged "$UNSTAGED_JSON" \ + --argjson untracked "$UNTRACKED_JSON" --arg branch "$BRANCH" \ + --argjson detached "$DETACHED" --arg short_sha "$SHORT_SHA" \ + --argjson upstream "$UPSTREAM_JSON" --argjson ahead "$AHEAD_JSON" \ + --arg primer "$PRIMER" --argjson learnings "$LEARNINGS_JSON" \ + --arg backlog_mode "$BACKLOG_MODE" --argjson backlog_fastpath_count "$BACKLOG_FASTPATH_COUNT" \ + --argjson commit_subject "$COMMIT_SUBJECT_JSON" \ + '{staged:$staged, unstaged:$unstaged, untracked:$untracked, branch:$branch, + detached:$detached, short_sha:$short_sha, upstream:$upstream, ahead:$ahead, + primer:$primer, learnings:$learnings, backlog_mode:$backlog_mode, + backlog_fastpath_count:$backlog_fastpath_count, commit_subject:$commit_subject}' \ + > "$JSON_TMP" + +source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/checklist-assemble.sh" 1; then + CHECKLIST="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/checklist-assemble.sh" "$TSV" < "$JSON_TMP")" +else + CHECKLIST="⚠️ $SC_REQUIRE_SCRIPT_MSG" +fi +rm -f "$TSV" "$JSON_TMP" + _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-3-gather-facts --duration="$_PERF_DURATION" +echo "$CHECKLIST" ``` -- **Backlog verdicts** — reuse the per-item verdicts from Step 1's - verification sub-block; re-run - `bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" .` - to get the post-close issue set. No new git command — the evidence was already - gathered in Step 1. - -Handle these edge cases explicitly: - -- **Not a git repo.** If `git rev-parse` fails, the precondition in Step 0 should have caught this, but belt-and-suspenders: report "⚠️ not inside a git repo" once and skip git-dependent rows. -- **Detached HEAD.** `git rev-parse --abbrev-ref HEAD` returns `HEAD`. Note "⚠️ detached HEAD at ``" in the unpushed-commits row. -- **No upstream.** `git rev-parse --abbrev-ref @{u}` fails. Note "⚠️ branch `` has no upstream — set one with `git push -u origin `" in the unpushed-commits row. +**Field notes — the values only you know, filled in before running the block above:** -### Emit the checklist - -**List every file enumerated by the git commands — do not summarize, filter, or pick a "primary" one.** If `git diff --cached --name-only` returns three files, the "Staged files" row lists all three. Same rule for the Unstaged and Untracked rows. The suggested-commit message may emphasize one theme, but the checklist rows are inventories, not summaries. - -Output using this structure. Use ✓ (green), ⚠️ (yellow), or → (suggestion): - -| Row | Marker | Content | -|---|---|---| -| Primer refresh | ✓ | "Primer refreshed and staged" OR "Primer updated (outstanding item(s) closed)" OR "Primer already current (no-op)" | -| New learnings | ✓ | "N LEARNINGS entry/entries captured (#X, \"\" …)" OR "No new learnings" | -| Backlog | checkmark if none stale, else warning | "N tracked — <k> appears-DONE (#N, evidence), <m> still-open (#N…), <j> manual (#N…)" OR "none tracked" | -| Staged files | ✓ | "Staged: <file1>, <file2>, …" OR "Nothing staged" | -| Unstaged modifications | ✓ if none, else ⚠️ | "No unstaged modifications" OR "⚠️ Unstaged: <file1>, <file2>, …" | -| Untracked files | ✓ if none, else ⚠️ | "No untracked files" OR "⚠️ N untracked: <file1>, <file2>, … — ignore, add, or delete?" | -| Unpushed commits | ✓ / ⚠️ | "Up to date with origin/<branch>" OR "⚠️ Branch <name> is N commits ahead of origin — push before closing?" OR the detached-HEAD / no-upstream variants | -| Suggested commit | → | Derived from staged files + captured learnings. Omit row entirely if nothing is staged. | - -**Backlog row — re-derive, do not cache.** Step 3 re-runs the helper AFTER any Step 1 closures the -user confirmed. The *set* of issues and the counts are recomputed against the -post-close GitHub list; only the per-item -verdicts (`still-open` / `appears-DONE` / `manual`) computed in Step 1 are -reused. If the user closed an issue at the Step 1 prompt, it is gone from the -list and absent from this row. Marker: ✓ if -every remaining item is `still-open` or `manual` (nothing stale lingering); -⚠️ if any remaining item is `appears-DONE` (a resolved item still listed). -Cite the evidence for each `appears-DONE` item inline. A `manual` item's -citation is either `"not auto-verifiable"` (genuinely non-code) or `"no -related commits since last refresh — not re-checked this session"` (skipped -by the overlap gate) — keep whichever citation Step 1 assigned, don't -collapse them to one phrase. When the fast path fired, skip re-deriving this -row altogether and use its own citation as specified there. - -### Suggested commit message - -If files are staged, derive a commit message from the pattern: - -- Only `.session-continuity/` staged → `docs: update session continuity`. -- `.session-continuity/LEARNINGS.md` is staged with code → pick the most prominent captured learning's title (or the primary code-change theme) and use conventional-commit style: `<type>(<scope>): <subject>`. Keep subject line ≤ 72 chars. -- Only code staged (no docs) → should not happen if Step 1 ran; if it does, suggest based on the file paths. - -Prefix with `→ Suggested:` and wrap in a fenced code block so the user can copy-paste. - -### Example output - -``` -✓ Primer refreshed and staged -✓ 1 LEARNINGS entry captured (#7, "awk range collapse on single-version CHANGELOG") -⚠️ Backlog: 5 tracked — 1 appears-DONE (4 [c7d1], "add bats test harness": found test/end_to_end.bats → 0 hits before, now present), 1 still-open (3 [b092]), 3 manual (1 [a3f9], 2 [7f3e], 5 [e8a4]) -✓ Staged: .session-continuity/SESSION_PRIMER.md, .session-continuity/LEARNINGS.md, .github/workflows/release.yml -✓ No unstaged modifications -⚠️ 2 untracked files: scratch.md, tmp/debug.log — ignore, add, or delete? -⚠️ Branch "main" is 3 commits ahead of origin — push before closing? -→ Suggested: - git commit -m "fix(ci): extract CHANGELOG section with proper awk range" -``` +- `BACKLOG_MODE` / `BACKLOG_FASTPATH_COUNT`: `"fast-path"` + the fast path's `<fast-path-backlog-count>` when Step 1's fast path fired; otherwise whichever of `none`/`unavailable`/`not-migrated`/`normal` Step 1's Backlog verification section landed on (its own skip conditions already tell you which). +- `TSV`: leave as computed above (empty string unless the in-repo scratch file existed and was copied out before deletion) — never override it by hand. +- `PRIMER`: `"refreshed"` if the refresh flow ran and staged the primer, `"closed"` if only the drift-clean close-candidate prompt ran and closed item(s), `"current"` if Step 1 was a no-op (fast path or drift-clean-zero-candidates). +- `LEARNINGS_JSON`: the accepted drafts from Step 2's capture flow, as `[{"number":N,"title":"..."}]`; `[]` if Step 2 captured nothing. +- `COMMIT_SUBJECT_JSON`: `"null"` (the bare word, unquoted) unless staged files exist AND at least one is outside `.session-continuity/` — in that case, a quoted JSON string with your conventional-commit subject (`<type>(<scope>): <subject>`, ≤72 chars), e.g. `'"fix(ci): extract CHANGELOG section with proper awk range"'`. Pick the theme from the most prominent captured learning's title, or the primary code-change theme — same judgment call as before this phase, just handed to the script instead of formatted by hand. -*(Illustrative only — the real Backlog row reflects the current primer's actual item set and verdicts.)* +**Output.** If `$CHECKLIST` starts with `⚠️` (the `require_script` failure) or `SC-FALLBACK:` (the script's own malformed-input escape), print it as a single warning line and assemble the checklist by hand this one time, following the row table that existed before this phase (Primer refresh / New learnings / Backlog / Staged files / Unstaged modifications / Untracked files / Unpushed commits / Suggested commit, each ✓/⚠️/→, backlog citing evidence for `appears-DONE` only) — then still emit Step 4's sign-off line yourself, choosing the warning-suffixed variant if any row you assembled carries ⚠️. Otherwise, print `$CHECKLIST` verbatim — it already ends with the terminal sign-off line; do not print anything after it except whatever Step 4's timing calls require. ## Step 4 — Terminal sign-off (always) From 17d866d97e476cd0838fe59379742f8b383c8d38 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Tue, 8 Sep 2026 13:53:12 -0700 Subject: [PATCH 09/20] refactor: end-session Step 4 becomes a pure timing step, sign-off now owned by checklist-assemble.sh --- commands/end-session.md | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/commands/end-session.md b/commands/end-session.md index 4d66275..54e98bb 100644 --- a/commands/end-session.md +++ b/commands/end-session.md @@ -522,9 +522,11 @@ echo "$CHECKLIST" **Output.** If `$CHECKLIST` starts with `⚠️` (the `require_script` failure) or `SC-FALLBACK:` (the script's own malformed-input escape), print it as a single warning line and assemble the checklist by hand this one time, following the row table that existed before this phase (Primer refresh / New learnings / Backlog / Staged files / Unstaged modifications / Untracked files / Unpushed commits / Suggested commit, each ✓/⚠️/→, backlog citing evidence for `appears-DONE` only) — then still emit Step 4's sign-off line yourself, choosing the warning-suffixed variant if any row you assembled carries ⚠️. Otherwise, print `$CHECKLIST` verbatim — it already ends with the terminal sign-off line; do not print anything after it except whatever Step 4's timing calls require. -## Step 4 — Terminal sign-off (always) +## Step 4 — Ritual timing (always) -After the checklist (and suggested-commit block, if any), emit a final closing line so the user knows the ritual completed and they are not blocked waiting for further prompts. +Step 3's `$CHECKLIST` already ended with the terminal sign-off line — this +step prints nothing of its own. It only logs how long the ritual took, so +the log carries one real end-to-end number per invocation. **Before that line, record total ritual time.** Each step above only timed its own Bash block, not the gaps between them — this reads back this @@ -577,21 +579,7 @@ block is skipped entirely — no `step-4-agent-active` line is logged for this invocation, same "skip rather than log a wrong number" rule that already governs the rest of this design. -**Always emit one of these two lines, exactly:** - -- If every checklist row was ✓ (no ⚠️ anywhere): - - ``` - ✅ Session complete. Safe to close. - ``` - -- If any checklist row had ⚠️: - - ``` - ✅ Session complete. Safe to close. (Warnings above are advisory — review before closing if relevant.) - ``` - -**Required.** Print this line on its own, after the checklist and any suggested-commit block. Never omit it. Never replace it with paraphrased prose. Never ask follow-up questions after this line — the line marks the end of the ritual. If the user wants to act on a warning, they will reply on their own. +**Never ask follow-up questions after Step 3's sign-off line printed.** It marks the end of the ritual. If the user wants to act on a warning, they will reply on their own. ## Notes From b7b82f3cc7a6d732765b68554d352e4c45a9405a Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Tue, 8 Sep 2026 14:00:09 -0700 Subject: [PATCH 10/20] docs: Phase 4 doc pointers, changelog, and version bump for the checklist script --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 5 +++++ .../2026-09-02-determinism-program-design.md | 15 +++++++++------ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index f2b5696..db77b33 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session-continuity", - "version": "0.29.1", + "version": "0.30.0", "description": "Cross-session memory for Claude Code projects via four in-repo docs: SESSION_PRIMER.md (current state), PROJECT_CONTEXT.md (stable repo context), ROADMAP.md (strategic direction), and LEARNINGS.md (hard-won bugs), plus GitHub Issues labeled backlog for the work queue.", "author": { "name": "Tal Golan" diff --git a/CHANGELOG.md b/CHANGELOG.md index 550a665..f7fcc47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.30.0] — 2026-09-08 + +### Changed +- **`end-session`'s Step 3 checklist is now scripted.** New `hooks/lib/checklist-assemble.sh` consumes the seven git-status outputs and a `tag/verdict/citation` backlog-verdict file, and prints all eight finished checklist rows, the backlog tallies, every ✓/⚠️ marker, the suggested-commit block, and the terminal sign-off line as one deterministic block. The model's job shrinks to deciding backlog verdicts (unchanged from before) and picking a commit-message theme when code is staged — everything else (file-list rendering, tallying, marker selection, sign-off wording) is no longer hand-formatted per invocation. Step 4 no longer prints anything; the sign-off line is now part of Step 3's script output. + ## [0.29.1] — 2026-09-07 ### Fixed diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index 356ee72..5f04ffe 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -180,12 +180,15 @@ check mode. Unblocks phases 4 and 6 and closes `52dc` as a side effect. is decided. Plan: `meta/superpowers/plans/2026-09-03-shared-mechanics-library.md`. -**Phase 4 `#41` — `end-session` Step 3 checklist assembly.** One script consuming the -six git outputs and a `tag<TAB>verdict<TAB>citation` file, emitting the eight -finished rows, the four backlog tallies, the per-row markers, and the sign-off -boolean (612-675, 759-773), retiring the example block at 687-701. Depends on -Phase 3's `since`. Removes the file-inventory summarization failure that -line 646 exists to prevent. +**Phase 4 `#41` — `end-session` Step 3 checklist assembly.** `checklist-assemble.sh` +consumes the (now seven — a `git rev-parse --short HEAD` was added for the +detached-HEAD row) git outputs plus a `tag<TAB>verdict<TAB>citation` scratch +file, emitting all eight finished rows, the backlog tallies, every marker, +and the terminal sign-off line as one block — Step 4 no longer prints +anything of its own. Removes the "list every file, do not summarize" +instruction and the illustrative example entirely; the script's own output +is the contract. Plan: +`meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md`. **Phase 5 `#42` — backlog mechanics.** Two scripts used by both `primer.md` and `end-session.md`: item bookkeeping (mint a 4-hex tag with a uniqueness grep, From 40f54968b3a6193b24a54372da01bd6c6dfbd807 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Tue, 8 Sep 2026 14:11:23 -0700 Subject: [PATCH 11/20] fix(docs): inline sign-off strings in end-session fallback path Step 4 no longer prints the two canonical sign-off strings (removed earlier in this plan), so the fallback-assembly paragraph in Step 3 had a dangling cross-reference to "Step 4's sign-off line". Inline the two literal strings (confirmed against hooks/lib/checklist-assemble.sh) so the fallback path is self-contained. Also reword "print $CHECKLIST verbatim" to "relay the block's printed checklist unchanged" to avoid reading as a request for a second echo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --- commands/end-session.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/end-session.md b/commands/end-session.md index 54e98bb..e0eb368 100644 --- a/commands/end-session.md +++ b/commands/end-session.md @@ -520,7 +520,7 @@ echo "$CHECKLIST" - `LEARNINGS_JSON`: the accepted drafts from Step 2's capture flow, as `[{"number":N,"title":"..."}]`; `[]` if Step 2 captured nothing. - `COMMIT_SUBJECT_JSON`: `"null"` (the bare word, unquoted) unless staged files exist AND at least one is outside `.session-continuity/` — in that case, a quoted JSON string with your conventional-commit subject (`<type>(<scope>): <subject>`, ≤72 chars), e.g. `'"fix(ci): extract CHANGELOG section with proper awk range"'`. Pick the theme from the most prominent captured learning's title, or the primary code-change theme — same judgment call as before this phase, just handed to the script instead of formatted by hand. -**Output.** If `$CHECKLIST` starts with `⚠️` (the `require_script` failure) or `SC-FALLBACK:` (the script's own malformed-input escape), print it as a single warning line and assemble the checklist by hand this one time, following the row table that existed before this phase (Primer refresh / New learnings / Backlog / Staged files / Unstaged modifications / Untracked files / Unpushed commits / Suggested commit, each ✓/⚠️/→, backlog citing evidence for `appears-DONE` only) — then still emit Step 4's sign-off line yourself, choosing the warning-suffixed variant if any row you assembled carries ⚠️. Otherwise, print `$CHECKLIST` verbatim — it already ends with the terminal sign-off line; do not print anything after it except whatever Step 4's timing calls require. +**Output.** If `$CHECKLIST` starts with `⚠️` (the `require_script` failure) or `SC-FALLBACK:` (the script's own malformed-input escape), print it as a single warning line and assemble the checklist by hand this one time, following the row table that existed before this phase (Primer refresh / New learnings / Backlog / Staged files / Unstaged modifications / Untracked files / Unpushed commits / Suggested commit, each ✓/⚠️/→, backlog citing evidence for `appears-DONE` only) — then still emit the terminal sign-off line yourself: `✅ Session complete. Safe to close.` if every row you assembled was ✓, or `✅ Session complete. Safe to close. (Warnings above are advisory — review before closing if relevant.)` if any row carries ⚠️. Otherwise, relay the block's printed checklist unchanged — it already ends with the terminal sign-off line; do not print anything after it except whatever Step 4's timing calls require. ## Step 4 — Ritual timing (always) From 8dfd9c93cbe2fc83503a25329a82074411f7f8f9 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Tue, 8 Sep 2026 15:29:53 -0700 Subject: [PATCH 12/20] refactor: end-session's overlap gate is now hooks/lib/token-overlap.sh/.jq (#51) Replaces the two hand-computed prose copies of the commit-subject/ backlog-title token-overlap check (Backlog verification's "Overlap gate" and the refresh flow's "backlog overlay") with one script call, run once and reused by both. The stopword list moves out of prose into the .jq filter. Re-scopes Phase 5 (#42): the original framing assumed primer.md still carried its own copy of this gate (it doesn't, since the GitHub Issues migration) and that candidate-extract.jq's overlap() -- a Jaccard-ratio function for LEARNINGS-candidate dedup, unrelated to this cardinality- threshold gate -- was the thing to lift. That function's own bug (c9a4) was already fixed and closed as #40 in the prior session (93c433f) -- unrelated to this change, not reopened. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --- .claude-plugin/plugin.json | 2 +- .session-continuity/SESSION_PRIMER.md | 27 ++++-- CHANGELOG.md | 5 + commands/end-session.md | 96 +++++++++++-------- hooks/lib/token-overlap.jq | 45 +++++++++ hooks/lib/token-overlap.sh | 54 +++++++++++ .../2026-09-02-determinism-program-design.md | 22 +++-- .../validation/2026-09-08-token-overlap.md | 32 +++++++ 8 files changed, 229 insertions(+), 54 deletions(-) create mode 100644 hooks/lib/token-overlap.jq create mode 100755 hooks/lib/token-overlap.sh create mode 100644 meta/superpowers/validation/2026-09-08-token-overlap.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index db77b33..7bf5b73 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session-continuity", - "version": "0.30.0", + "version": "0.31.0", "description": "Cross-session memory for Claude Code projects via four in-repo docs: SESSION_PRIMER.md (current state), PROJECT_CONTEXT.md (stable repo context), ROADMAP.md (strategic direction), and LEARNINGS.md (hard-won bugs), plus GitHub Issues labeled backlog for the work queue.", "author": { "name": "Tal Golan" diff --git a/.session-continuity/SESSION_PRIMER.md b/.session-continuity/SESSION_PRIMER.md index abeb74f..ba60047 100644 --- a/.session-continuity/SESSION_PRIMER.md +++ b/.session-continuity/SESSION_PRIMER.md @@ -20,6 +20,22 @@ rarely. ## Current state +- **Determinism Phase 5 re-scoped and shipped (issue #42, branch + `determinism-phase-5-token-overlap`).** Original scoping conflated two + unrelated things: `candidate-extract.jq`'s `overlap()` (a Jaccard ratio + for LEARNINGS-candidate dedup — already fixed and closed as #40, see + the bullet below, unrelated to this work) and the commit-subject / + backlog-issue-title cardinality-threshold gate duplicated as two prose + copies inside `commands/end-session.md` (the "Overlap gate" in Backlog + verification and the refresh flow's "backlog overlay" — primer.md's own + copy had already vanished with the GitHub Issues migration, so it was + never really "shared with primer.md" as originally framed). Shipped + `hooks/lib/token-overlap.sh`/`.jq`: tokenize, drop stopwords, intersect, + threshold ≥3, computed once per `end-session` run and reused by both + call sites; stopword list moved out of prose into the `.jq` filter. + 6 fixture cases verified (real match, near-miss, stopword-only overlap, + empty issues/commits, multiplicity dedup, missing-file failure) — see + `meta/superpowers/validation/2026-09-08-token-overlap.md`. v0.31.0. - **Closes backlog #40: `overlap()`'s asymmetric Jaccard in `hooks/lib/candidate-extract.jq` over-merged distinct retry-bursts.** The numerator (`$wa - ($wa - $wb)`) counted `$wa`'s own word @@ -656,12 +672,11 @@ rarely. **Current `git log --oneline -5` (primary branch):** ``` -c9ecacc Merge pull request #49 from talgolan/worktree-docguard-generalization -d36d472 docs: don't claim GitHub issue #38 is closed until it actually is -8b11c46 docs: mark docguard generalization implemented, correct hard-block assumption -db8ec26 Merge pull request #48 from talgolan/fix/ghe-backlog-origin-check -16f8d06 fix: recognize GitHub Enterprise Server origins for the backlog queue -ff6b8c8 test: bump stale count-entries-smoke pins to real BACKLOG/LEARNINGS counts (16/18) +66468ee refactor: end-session's overlap gate is now hooks/lib/token-overlap.sh/.jq +ddaccca Merge pull request #50 from talgolan/determinism-phase-4-step3-checklist +40f5496 fix(docs): inline sign-off strings in end-session fallback path +b7b82f3 docs: Phase 4 doc pointers, changelog, and version bump for the checklist script +17d866d refactor: end-session Step 4 becomes a pure timing step, sign-off now owned by checklist-assemble.sh ``` Regenerate this block whenever you commit — see diff --git a/CHANGELOG.md b/CHANGELOG.md index f7fcc47..eb09770 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.31.0] — 2026-09-08 + +### Changed +- **`end-session`'s commit-subject/backlog-title overlap gate is now scripted.** New `hooks/lib/token-overlap.sh` / `token-overlap.jq` replace two hand-computed prose copies of the same tokenize-and-threshold algorithm (the "Overlap gate" in Backlog verification and the refresh flow's "backlog overlay"), computed once per `end-session` run and reused by both. The hardcoded stopword list moved out of prose into the `.jq` filter. This is unrelated to `candidate-extract.jq`'s `overlap()` (a Jaccard-ratio function used for LEARNINGS-candidate dedup, already fixed and closed as issue #40 in the prior session) — the two "overlap" concepts were previously conflated in Phase 5's original scoping. + ## [0.30.0] — 2026-09-08 ### Changed diff --git a/commands/end-session.md b/commands/end-session.md index e0eb368..60837d0 100644 --- a/commands/end-session.md +++ b/commands/end-session.md @@ -72,13 +72,19 @@ overlap gate below and the Refresh flow's overlay further down — compute it here, don't recompute it there. **Data source.** Run -`bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" .` + +```bash +mkdir -p .session-continuity +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" . > .session-continuity/.end-session-issues.txt +cat .session-continuity/.end-session-issues.txt +``` + and identify each item by `#N`. Do not read `.session-continuity/BACKLOG.md`. **Skip conditions.** -- If the helper prints `No open backlog issues.`: skip verification. +- If the file's content is `No open backlog issues.`: skip verification. Step 3's row reads `Backlog: none tracked`. -- If the helper prints the GitHub-unavailable warning: skip verification. +- If the file's content is the GitHub-unavailable warning: skip verification. Step 3's row reads `Backlog: GitHub queue unavailable — run /session-continuity:doctor`. - If the primer still has an inline `## Outstanding items` heading or `.session-continuity/OUTSTANDING_ITEMS.md` exists: tell the user once @@ -86,22 +92,42 @@ and identify each item by `#N`. Do not read `.session-continuity/BACKLOG.md`. `/session-continuity:end-session`. Step 3's row reads `Backlog: not migrated — run /session-continuity:primer`. -**For each open issue** (`N. #NUMBER Title` from the helper). Identify +**For each open issue** (`N. #NUMBER Title` from the file). Identify the item by `#NUMBER`, never by the ephemeral 1..N list position. -**Overlap gate (cost control) — run this before classifying.** Tokenize the -issue title (same rule as the overlay below: lowercase, split on non-alphanumeric, -drop tokens <3 chars, drop the overlay's stopword list) and compare against -each commit subject in the list computed above, tokenized the same way. If -the intersection with EVERY commit subject has cardinality <3 — nothing that -landed since the last refresh implicates this item — skip the -classify/verify steps below for this item. Assign verdict **`manual`**, cited -as `"no related commits since last refresh — not re-checked this session"`. -This is the deliberate accuracy tradeoff of the gate: an item resolved -through means that leave no matching commit subject (a manual/external fix) -won't be caught until a touching commit lands or the user mentions it -directly. Items with cardinality ≥3 against at least one commit subject -proceed to full classify/verify below. +**Token overlap (cost control) — compute once, reuse here and in the refresh +flow further down.** Write the commit list (from "Compute the commit list +once" above) to a file, then run the shared gate script once against the +issues file already written above: + +```bash +git log <last-primer-commit>..HEAD --oneline > .session-continuity/.end-session-commits.txt +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/token-overlap.sh" \ + .session-continuity/.end-session-issues.txt \ + .session-continuity/.end-session-commits.txt \ + > .session-continuity/.end-session-overlap.tsv +``` + +The result is a TSV of every `#N<TAB>commit subject` pair whose tokenized +titles share ≥3 tokens (short tokens and stopwords dropped first) — the +single source of truth for this section's skip decision and the refresh +flow's backlog overlay. **Read every row — do not summarize, filter, or +sample the output; a missing row for a real match is a silent skip.** Empty +output is a normal outcome (zero matches), not a failure signal. If the +script itself fails (nonzero exit), treat its output as empty and continue +— every item then proceeds to full classify/verify below instead of being +gated, which is the conservative direction. + +**Overlap gate.** For each item, check whether `#N` appears anywhere in +`.session-continuity/.end-session-overlap.tsv`. If it does not — no commit since the last +refresh reached the ≥3-token-overlap threshold for this item — skip the +classify/verify steps below for this item. Assign verdict **`manual`**, +cited as `"no related commits since last refresh — not re-checked this +session"`. This is the deliberate accuracy tradeoff of the gate: an item +resolved through means that leave no matching commit subject (a +manual/external fix) won't be caught until a touching commit lands or the +user mentions it directly. If `#N` appears against at least one commit +subject, proceed to full classify/verify below. 1. **Classify — code-verifiable or not.** An item is code-verifiable if a `grep`/`glob`/file-exists check *could* speak to it (it names a file, a @@ -255,36 +281,30 @@ Follow the logic in **Step 5 of `commands/primer.md`** (refresh mode): 2. If the primer has a test-counts section and the counts changed (after the 3× retry), update them to match current output. 3. **Surface commits since the last primer refresh, with backlog overlay.** Reuse the commit list already computed in the Backlog verification section above (`git log <last-primer-commit>..HEAD --oneline`) — do not recompute it. Present the subject list as candidate prompts. - Then compute a **backlog overlay** for each subject: - - - Tokenize the subject: lowercase, split on non-alphanumeric, drop tokens of length <3, drop the stopword list below. - - For each open backlog issue from the helper: tokenize the title the same way. - - Match if the intersection of subject tokens and item tokens has cardinality ≥ 3. - - **Stopwords** (extend per project as needed): - - ``` - the and for fix add update from with into feat chore docs primer learnings session continuity tag version release - ``` + Then look up the **backlog overlay** for each subject: filter + `.session-continuity/.end-session-overlap.tsv` (computed once in the + Backlog verification section above — do not recompute) for rows whose + commit-subject column equals this subject. The `#N` values on those rows + are the matching issues. **List every matching row for the subject — do + not summarize or pick one.** **Presentation.** Render the "May close outstanding items" block when EITHER token-overlap matches from commit subjects OR `appears-DONE` items from the Backlog verification sub-block above exist. **Render candidates as - a markdown ordered list, one item per line, using the item's current - `<position>` as the list ordinal** (e.g. `4. [a3f9] <cited code evidence> — <sha>`) - so the numbering the user sees matches the numbering in the primer — never a - bare bullet list or an inline comma-separated citation. Cite each - candidate by tag: commit-subject matches as `<sha> → item [a3f9]`, verification - candidates as `item [a3f9] (<cited code evidence>)`. Dedupe by tag (never by - position — it's recomputed per render and not a stable key): an item that is - both a commit-subject match and an `appears-DONE` candidate appears once, on - a single numbered line carrying both the `<sha>` and the code-evidence + a markdown ordered list, one item per line, identified by `#N`** (e.g. + `4. #40 <cited code evidence> — <sha>`) — never a bare bullet list or an + inline comma-separated citation. Cite each candidate by tag: commit-subject + matches as `<sha> → item #40`, verification candidates as `item #40 (<cited + code evidence>)`. Dedupe by `#N` (the stable issue identity — never by list + position, which is recomputed per render): an item that is both a + commit-subject match and an `appears-DONE` candidate appears once, on a + single numbered line carrying both the `<sha>` and the code-evidence citation. Omit the block only when BOTH sources are empty (do not print an empty section). **Refusal.** Never close an outstanding item without explicit user confirmation. The overlay is a candidate list, not an auto-close. - **Skip conditions.** If the helper printed a warning or `No open backlog issues.`, skip the overlay silently — the raw subject list still appears. + **Skip conditions.** If `.session-continuity/.end-session-issues.txt` is `No open backlog issues.` or the GitHub-unavailable warning, skip the overlay silently — the raw subject list still appears. 4. **Single combined prompt.** After printing the subject list (and overlay block if any), log a prompt-shown marker (same mechanism as the drift-clean prompt above — isolates human-response wait from ritual compute time, see Step 4): ```bash diff --git a/hooks/lib/token-overlap.jq b/hooks/lib/token-overlap.jq new file mode 100644 index 0000000..0296fda --- /dev/null +++ b/hooks/lib/token-overlap.jq @@ -0,0 +1,45 @@ +# CONTRACT_VERSION=1 +# hooks/lib/token-overlap.jq — commit-subject / backlog-issue-title token +# overlap. Invoked via token-overlap.sh; see that file for the CLI contract. +# +# This is the cardinality-threshold overlap gate (tokenize, drop stopwords, +# intersect, threshold >=3) used to decide whether a commit plausibly +# touches a backlog item. It is unrelated to candidate-extract.jq's +# overlap() (a Jaccard *ratio* used for LEARNINGS-candidate dedup) — the two +# solve different problems and must not be conflated. + +def stopwords: [ + "the","and","for","fix","add","update","from","with","into","feat", + "chore","docs","primer","learnings","session","continuity","tag", + "version","release" +]; + +def tokenize: + ascii_downcase + | gsub("[^a-z0-9]+"; " ") + | [splits(" +")] + | map(select(length >= 3)) + | map(select(. as $t | (stopwords | index($t)) == null)) + | unique; + +def parse_issue_line: + try (capture("^[0-9]+\\.\\s+#(?<n>[0-9]+)\\s+(?<title>.+)$")) catch null; + +def parse_commit_line: + try (capture("^\\S+\\s+(?<subject>.+)$")) catch null; + +($issues_raw | split("\n") | map(select(length > 0)) | map(parse_issue_line) + | map(select(. != null)) + | map({id: ("#" + .n), tokens: (.title | tokenize)}) +) as $issues + +| ($commits_raw | split("\n") | map(select(length > 0)) | map(parse_commit_line) + | map(select(. != null)) + | map({subject: .subject, tokens: (.subject | tokenize)}) + ) as $commits + +| $issues[] as $i +| $commits[] as $c +| ($i.tokens - ($i.tokens - $c.tokens)) as $inter +| select(($inter | length) >= 3) +| "\($i.id)\t\($c.subject)" diff --git a/hooks/lib/token-overlap.sh b/hooks/lib/token-overlap.sh new file mode 100755 index 0000000..5720b92 --- /dev/null +++ b/hooks/lib/token-overlap.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/token-overlap.sh — commit-subject / backlog-issue-title token +# overlap gate. Replaces the two hand-computed prose copies that used to +# live in commands/end-session.md (the "Overlap gate" and the refresh +# flow's "backlog overlay") with one deterministic computation, run once. +# +# Usage: token-overlap.sh <issues-file> <commits-file> +# <issues-file> — raw backlog-issues.sh list output, one issue per line: +# "N. #NUMBER Title text" +# <commits-file> — raw `git log --oneline <range>` output, one commit per +# line: "<abbrev-hash> subject text" +# +# Prints TSV to stdout, one line per (issue, commit) pair whose tokenized +# titles share >=3 tokens after dropping short tokens and stopwords: +# #NUMBER<TAB>commit subject +# Zero matches is a normal, silent outcome (empty stdout, exit 0) — the +# caller treats "no line for this issue" / "no line for this subject" as +# "no match," not as an error. +# +# Operational failure (jq missing, filter missing/wrong version, a missing +# input file) prints one diagnostic line to stderr and exits 1. Callers +# that don't check the exit code still degrade safely: empty stdout reads +# as zero matches either way, which is the conservative direction for both +# call sites (skip-with-manual-verdict, or no overlay suggestion). + +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JQ_FILTER="$SCRIPT_DIR/token-overlap.jq" +ISSUES_FILE="${1:-}" +COMMITS_FILE="${2:-}" + +die() { + printf 'token-overlap.sh: %s\n' "$1" >&2 + exit 1 +} + +[[ -n "$ISSUES_FILE" && -n "$COMMITS_FILE" ]] \ + || die "usage: token-overlap.sh <issues-file> <commits-file>" +[[ -r "$ISSUES_FILE" ]] || die "issues file is not readable: $ISSUES_FILE" +[[ -r "$COMMITS_FILE" ]] || die "commits file is not readable: $COMMITS_FILE" +command -v jq >/dev/null 2>&1 \ + || die "jq is not installed, so the overlap gate cannot run." +[[ -r "$JQ_FILTER" ]] \ + || die "token-overlap.jq is missing from $SCRIPT_DIR — the plugin cache is incomplete. Run \`/session-continuity:update\`." +grep -q '^# CONTRACT_VERSION=1$' "$JQ_FILTER" \ + || die "token-overlap.jq is from a different plugin version — run \`/session-continuity:update\`." + +ISSUES_RAW="$(cat "$ISSUES_FILE")" +COMMITS_RAW="$(cat "$COMMITS_FILE")" + +jq -r -n --arg issues_raw "$ISSUES_RAW" --arg commits_raw "$COMMITS_RAW" -f "$JQ_FILTER" \ + || die "the overlap filter failed." diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index 5f04ffe..303a7fa 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -190,15 +190,19 @@ instruction and the illustrative example entirely; the script's own output is the contract. Plan: `meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md`. -**Phase 5 `#42` — backlog mechanics.** Two scripts used by both `primer.md` and -`end-session.md`: item bookkeeping (mint a 4-hex tag with a uniqueness grep, -stamp the date, renumber positions 1..N, grep the repo for a tag before -deletion) and the overlap gate (tokenize, drop short tokens and stopwords, -intersect with commit subjects, threshold at 3). The overlap algorithm -currently exists as two prose copies that can drift, and -`candidate-extract.jq:96-107` already has a working token-overlap -implementation to lift. Set-intersection cardinality is a task models get -wrong silently. +**Phase 5 `#42` — token-overlap gate (re-scoped 2026-09-08).** Original framing +above was stale on two counts: item bookkeeping (hex-tag mint/renumber/ +grep-delete) is gone with the GitHub Issues migration, and `primer.md` no +longer carries its own copy of the gate — only `end-session.md` does, in +two spots (the "Overlap gate" in Backlog verification and the refresh +flow's "backlog overlay"). `candidate-extract.jq`'s `overlap()` is a +Jaccard *ratio* for LEARNINGS-candidate dedup, not the same algorithm as +this cardinality-threshold gate; lifting it here would have been wrong +(already fixed and closed as #40 in the prior session, unrelated to this +change). Shipped as `hooks/lib/token-overlap.sh`/`.jq`: +tokenize, drop short tokens and stopwords, intersect, threshold at 3 — +computed once per `end-session` run, reused by both call sites. Set- +intersection cardinality is a task models get wrong silently. **Phase 6 `#43` — `primer` detect, migrate, init, drift.** Mode detection plus migration triggers (11-60, pure boolean logic over file existence); the diff --git a/meta/superpowers/validation/2026-09-08-token-overlap.md b/meta/superpowers/validation/2026-09-08-token-overlap.md new file mode 100644 index 0000000..011c75f --- /dev/null +++ b/meta/superpowers/validation/2026-09-08-token-overlap.md @@ -0,0 +1,32 @@ +# Validation log — token-overlap gate consolidation (Determinism Phase 5, #42) + +**Branch:** `determinism-phase-5-token-overlap` + +Fixture-driven checks of `hooks/lib/token-overlap.sh` / +`hooks/lib/token-overlap.jq`, run directly (no bats/test harness exists in +this repo yet — see open issue #36). Each case is a scratch issues-file / +commits-file pair passed straight to the script. + +| # | Case | Input | Result | Expected | +|---|------|-------|--------|----------| +| 1 | Real match | issue title and commit subject share `determinism`, `phase`, `5`, `overlap`, `gate` (≥3 non-stopword tokens) | one row `#42\t<subject>` | one row | +| 2 | Near-miss | only `phase`/`5`-adjacent overlap below threshold | empty | empty | +| 3 | Stopword-only overlap | shared words (`fix`, `and`, `update`, `the`, `docs`) are entirely in the stopword list | empty | empty — proves stopwords are dropped before counting, not just documented | +| 4a | Empty issues file | — | empty, exit 0 | empty | +| 4b | Empty commits file | — | empty, exit 0 | empty | +| 5 | Multiplicity | issue title repeats `overlap` 3×; only 2 *distinct* tokens (`overlap`, `gate`) are actually shared | empty (cardinality 2 < 3) | empty — proves each token set is deduped before intersecting, so multiplicity can't inflate cardinality (the class of bug split out to #40 for `candidate-extract.jq`'s unrelated Jaccard-ratio function) | +| 6 | Missing input file | nonexistent path | stderr diagnostic, exit 1 | non-zero exit, no crash | + +All six matched expectation. `commands/end-session.md`'s two prose copies +(the "Overlap gate" in Backlog verification and the refresh flow's "backlog +overlay") were replaced with two reads of one `.end-session-overlap.tsv` +computed by a single script invocation; the stopword list moved out of +prose entirely into `token-overlap.jq`. + +**Not exercised here:** the full `end-session.md` flow end-to-end against a +real scratch repo (that level of validation exists for other Phase work, +e.g. `2026-08-17-performance-logging.md`) — this task changes an internal +computation swapped in place of equivalent prose, with the same inputs +(`backlog-issues.sh`, `git log --oneline`) and output contract (`#N` +identity, TSV) the surrounding prose already expected, so a full command +run was judged unnecessary for this size of change. From de381a8e4863685540c5910ac61530bf4c9076c5 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Tue, 8 Sep 2026 17:03:14 -0700 Subject: [PATCH 13/20] feat: primer-detect.sh/.jq, scripting /session-continuity:primer's Step 1 dispatch (Phase 6 sub-project A) (#52) * docs: design spec for primer-detect.sh/.jq (Phase 6 sub-project A) Re-scopes Determinism Phase 6 (#43) into five independent sub-projects after finding the original design-spec entry predates Step 3d (BACKLOG.md -> GitHub Issues, added in the 2026-09-07 migration). This spec covers only sub-project A: Step 1's detect/dispatch logic, the highest-frequency and zero-judgment piece of the phase. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: correct backlog_to_issues trigger condition in primer-detect spec Caveman-review caught a real inconsistency: the spec's stated condition (BACKLOG_EXISTS=1) contradicted its own worst-case fixture, which chains backlog_rename -> backlog_to_issues in one STEPS output despite BACKLOG_EXISTS=0 being backlog_rename's own precondition. STEPS is computed from a single upfront fact snapshot -- no step has run yet at decision time -- so the trigger needs an explicit disjunction: fire now if BACKLOG_EXISTS=1, or fire anyway if backlog_rename is about to make it true. Also states explicitly that all facts are always emitted regardless of branch, and rewords the refresh-decision paragraph to stop implying it waits for migrations to execute first. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: primer-detect spec's dependency chain, one link deeper than the first fix Implementing the state machine against real jq surfaced a second instance of the bug caveman-review caught: backlog_rename's own condition (OUTSTANDING_ITEMS_EXISTS=1 AND BACKLOG_EXISTS=0) has the same problem the earlier fix solved for backlog_to_issues -- outstanding_split, if also queued, is what's about to make OUTSTANDING_ITEMS_EXISTS true, so a bare snapshot check silently drops backlog_rename whenever it's chained after outstanding_split. A second disjunction would work but doesn't generalize past one link. Replaced both disjunctions with a single "thread the projected fact forward" formulation, verified directly against all 11 fixtures in jq before writing this fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat: add primer-detect.sh/.jq, scripting /session-continuity:primer's dispatch decision Ports the state machine from the primer-detect design spec into an executable pair: primer-detect.jq (pure filter logic, directly testable) and primer-detect.sh (I/O wrapper). Includes hermetic smoke suite with 16 assertions covering all decision paths and error conditions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * refactor: primer.md Step 1 dispatches via primer-detect.sh * docs: Phase 6 sub-project A doc pointers, changelog, and version bump * fix: primer.md's terminal-step rule covers migration-only STEPS lists Final whole-branch review found Step 1's dispatch rule only ran Step 5 when STEPS was fully empty, missing the migration-only case (STEPS non-empty but no refresh) entirely -- migrations ran but the terminal status report never fired, a real behavior gap versus the old system. The same rule change also resolves a related double-refresh risk when a migration step's own untouched 'fall through' language could re-trigger Step 4 after STEPS already lists refresh separately. Also fixes two doc-only inaccuracies: the design spec's Testing item 11 described its own fixture backwards (said the outstanding/backlog files already existed, when the fixture's whole point is that they don't -- that's what forces the chain through both projected-fact links), and stale case-count summaries in the spec and plan that didn't match the shipped 16-assertion smoke test. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 5 + commands/primer.md | 119 +-- hooks/lib/primer-detect.jq | 77 ++ hooks/lib/primer-detect.sh | 90 +++ .../plans/2026-09-08-primer-detect.md | 718 ++++++++++++++++++ .../2026-09-02-determinism-program-design.md | 23 +- .../specs/2026-09-08-primer-detect-design.md | 183 +++++ .../2026-09-08-primer-detect-smoke.zsh | 161 ++++ 9 files changed, 1309 insertions(+), 69 deletions(-) create mode 100644 hooks/lib/primer-detect.jq create mode 100755 hooks/lib/primer-detect.sh create mode 100644 meta/superpowers/plans/2026-09-08-primer-detect.md create mode 100644 meta/superpowers/specs/2026-09-08-primer-detect-design.md create mode 100755 meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 7bf5b73..1654d50 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session-continuity", - "version": "0.31.0", + "version": "0.32.0", "description": "Cross-session memory for Claude Code projects via four in-repo docs: SESSION_PRIMER.md (current state), PROJECT_CONTEXT.md (stable repo context), ROADMAP.md (strategic direction), and LEARNINGS.md (hard-won bugs), plus GitHub Issues labeled backlog for the work queue.", "author": { "name": "Tal Golan" diff --git a/CHANGELOG.md b/CHANGELOG.md index eb09770..1cca560 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.32.0] — 2026-09-08 + +### Changed +- **`/session-continuity:primer`'s Step 1 dispatch is now scripted.** New `hooks/lib/primer-detect.sh`/`.jq` replace ~15 lines of hand-evaluated nested-conditional prose (a 4-state classification plus 3 migration triggers with an easy-to-miss sequencing rule) with one script call that prints a definitive, ordered `STEPS=` list. The trigger chain is evaluated by threading each trigger's effect forward into the fact the next depends on (`outstanding_split → backlog_rename → backlog_to_issues`), not by re-deriving disjunctions per trigger — an approach tried and found not to compose past one chained link during this work. Determinism Phase 6 (#43) sub-project A; sub-projects B–E remain pending. + ## [0.31.0] — 2026-09-08 ### Changed diff --git a/commands/primer.md b/commands/primer.md index f94a088..f0ac916 100644 --- a/commands/primer.md +++ b/commands/primer.md @@ -10,58 +10,59 @@ You are responding to the `/session-continuity:primer` slash command. ## Step 1 — Detect state -Gather the raw data for every check below in **one Bash call**, timed: +Run the shared dispatch script once, timed: ```bash _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") -[ -f .session-continuity/SESSION_PRIMER.md ] && echo "PRIMER_EXISTS=1" || echo "PRIMER_EXISTS=0" -[ -f .session-continuity/LEARNINGS.md ] && echo "LEARNINGS_EXISTS=1" || echo "LEARNINGS_EXISTS=0" -[ -f .session-continuity/PROJECT_CONTEXT.md ] && echo "PROJECT_CONTEXT_EXISTS=1" || echo "PROJECT_CONTEXT_EXISTS=0" -[ -f .session-continuity/OUTSTANDING_ITEMS.md ] && echo "OUTSTANDING_ITEMS_EXISTS=1" || echo "OUTSTANDING_ITEMS_EXISTS=0" -grep -q '^## Outstanding items' .session-continuity/SESSION_PRIMER.md 2>/dev/null && echo "PRIMER_HAS_INLINE_OUTSTANDING=1" || echo "PRIMER_HAS_INLINE_OUTSTANDING=0" -[ -f .session-continuity/BACKLOG.md ] && echo "BACKLOG_EXISTS=1" || echo "BACKLOG_EXISTS=0" -[ -f .session-continuity/ROADMAP.md ] && echo "ROADMAP_EXISTS=1" || echo "ROADMAP_EXISTS=0" -git remote get-url origin 2>/dev/null || echo "NO_ORIGIN" -git log --oneline -5 -git diff --cached --name-only +source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-detect.sh" 1; then + DETECT_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-detect.sh" . 2>&1)" + DETECT_STATUS=$? +else + DETECT_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + DETECT_STATUS=1 +fi _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-1-detect-state --duration="$_PERF_DURATION" +echo "$DETECT_OUTPUT" +echo "DETECT_STATUS=$DETECT_STATUS" ``` -Interpret the output: - -1. Do `.session-continuity/SESSION_PRIMER.md` and `.session-continuity/LEARNINGS.md` exist? (`PRIMER_EXISTS` / `LEARNINGS_EXISTS` above.) -2. If a primer exists, does the `git log --oneline -5` block inside it match the `git log --oneline -5` output above? (mtime is intentionally not checked — formatters, save-on-blur, and `cat | tee` all bump mtime without changing content. The log-block diff is the authoritative drift signal.) -3. Does the `git diff --cached --name-only` output above contain any file outside `docs/`, `.session-continuity/`, `README*`, `CHANGELOG*`, `LICENSE*`? (Code is staged and a commit is imminent — the primer will be stale the moment that commit lands.) -4. If a primer exists, does `.session-continuity/PROJECT_CONTEXT.md` also exist? (`PROJECT_CONTEXT_EXISTS` above.) - -Four states result: - -- **No primer** → init mode (Step 2) -- **Primer exists but unsplit** (no `PROJECT_CONTEXT.md` yet) → split mode (Step 3) -- **Primer exists but stale** (log block drifted or code staged for commit) → refresh mode (Step 4) -- **Primer exists and current** (nothing staged) → check mode (Step 5) - -If `PRIMER_HAS_INLINE_OUTSTANDING=1` AND `OUTSTANDING_ITEMS_EXISTS=0`, -outstanding-items migration is needed — run it (Step 3b below) in addition -to whichever of the four states above applies. **Sequencing:** if the -primer is also unsplit (no `PROJECT_CONTEXT.md`), run the existing Split -mode (Step 3) to completion first, then run Step 3b against the resulting -primer, as two sequential edits — not simultaneous partitioning. The two -splits touch disjoint sections of the primer (stable-context headings vs. -the Outstanding items heading), so sequencing avoids any edit conflict. - -If `OUTSTANDING_ITEMS_EXISTS=1` AND `BACKLOG_EXISTS=0`, a file-rename -migration is needed — run it (Step 3c below) in addition to whichever of -the four states above applies. **Sequencing:** if Step 3b also fired this -run (inline heading present, no file yet), run Step 3b to completion -first — it still writes `OUTSTANDING_ITEMS.md` under the old name — then -run Step 3c against that result. Step 3c is strictly the one-level-up -file rename; it never inspects primer content. - -If `BACKLOG_EXISTS=1` (including after Step 3c) AND origin contains -`github.com`, run Step 3d (markdown backlog → GitHub Issues) after 3c. +**If `DETECT_STATUS` is nonzero, or `$DETECT_OUTPUT` has no `STEPS=` line: +stop.** Report `$DETECT_OUTPUT` to the user (it carries the diagnostic +either way — `require_script`'s message, or `primer-detect.sh`'s own +stderr, merged into stdout above) and do not execute any step below — +there is no safe default dispatch, since some steps run destructive +migrations (`git mv` in Step 3c, `git rm` in Step 3d). + +**Otherwise**, read `STEPS=` from `$DETECT_OUTPUT` and **execute every +name it lists, in the order given, then stop.** Do not re-derive which +steps should run from the individual `KEY=value` facts printed above +`STEPS=` — those are for transparency/debugging only, not a second +source of dispatch truth. If `STEPS` does not contain `refresh`, run Step 5 (check mode) as the +final step, after everything else `STEPS` named — this covers both the +fully-empty case (primer is current, nothing else to do) and a +migrations-only case (migrations ran, but the primer itself isn't +otherwise stale; Step 5's status report is still owed). If `STEPS` +contains `refresh`, Step 4 is the terminal step — its own reporting +already covers what Step 5 would say, so do not run Step 5 afterward. + +| Name in `STEPS` | Run | +|---|---| +| `init` | Step 2 (the only value `STEPS` can ever carry alone) | +| `split` | Step 3 | +| `outstanding_split` | Step 3b | +| `backlog_rename` | Step 3c | +| `backlog_to_issues` | Step 3d | +| `refresh` | Step 4 | + +Steps 3, 3b, 3c, and 3d's own bodies still say to "fall through" to +refresh or check mode after they finish — that phrasing predates this +dispatch. Treat it as already satisfied by the rule above: continue to +the next name in `STEPS` (if any), then apply the refresh/Step-5 rule +once, at the very end. Do not let a step's own fall-through sentence +trigger Step 4 or Step 5 a second time. ## Step 2 — Init mode @@ -173,11 +174,11 @@ contains). ## Step 3b — Outstanding-items split -Runs whenever `PRIMER_HAS_INLINE_OUTSTANDING=1` and -`OUTSTANDING_ITEMS_EXISTS=0` (see Step 1). Extract the primer's inline -`## Outstanding items` section into the new file; this is a one-time -content move, no numbering changes — the items keep whatever numbers -they currently have, and those become the first permanent IDs. +Runs when `outstanding_split` appears in Step 1's `STEPS`. Extract the +primer's inline `## Outstanding items` section into the new file; this +is a one-time content move, no numbering changes — the items keep +whatever numbers they currently have, and those become the first +permanent IDs. 1. Read the existing `.session-continuity/SESSION_PRIMER.md` in full. 2. Copy every top-level numbered item under `## Outstanding items` @@ -207,11 +208,11 @@ they currently have, and those become the first permanent IDs. ## Step 3c — Backlog rename migration -Runs whenever `BACKLOG_EXISTS=0` AND `OUTSTANDING_ITEMS_EXISTS=1` (see -Step 1). This is strictly the `OUTSTANDING_ITEMS.md` → `BACKLOG.md` -rename, one level up from Step 3b (which may have just created -`OUTSTANDING_ITEMS.md` under its old name this same run — Step 3c runs -after it, per the sequencing note in Step 1). +Runs when `backlog_rename` appears in Step 1's `STEPS`. This is strictly +the `OUTSTANDING_ITEMS.md` → `BACKLOG.md` rename, one level up from Step +3b (which may have just created `OUTSTANDING_ITEMS.md` under its old +name this same run — `STEPS` already places `backlog_rename` after +`outstanding_split` when both fire). 1. `git mv .session-continuity/OUTSTANDING_ITEMS.md .session-continuity/BACKLOG.md`. 2. Rewrite the moved file's first heading line from `# Outstanding Items @@ -248,11 +249,11 @@ split/migration step in this command. ## Step 3d — BACKLOG.md → GitHub Issues -Runs whenever `BACKLOG_EXISTS=1` (including after Step 3c just created -it) AND Step 1's origin URL contains `github.com`. If origin is missing -or not github.com, leave the file in place as a fossil and tell the -user `/session-continuity:doctor` will warn that the queue is inactive. -Do not keep writing to the fossil. +Runs when `backlog_to_issues` appears in Step 1's `STEPS`. If it doesn't +(non-github origin, or no backlog to migrate), leave any existing +`BACKLOG.md` in place as a fossil and tell the user +`/session-continuity:doctor` will warn that the queue is inactive. Do +not keep writing to the fossil. 1. `gh label create backlog --description "Agent backlog (session-continuity)" --force` 2. For each `### N. [tag] [YYYY-MM-DD] Title` heading whose title is diff --git a/hooks/lib/primer-detect.jq b/hooks/lib/primer-detect.jq new file mode 100644 index 0000000..c152db0 --- /dev/null +++ b/hooks/lib/primer-detect.jq @@ -0,0 +1,77 @@ +# CONTRACT_VERSION=1 +# hooks/lib/primer-detect.jq — /session-continuity:primer dispatch decision. +# Invoked via primer-detect.sh; see that file for the CLI contract and +# meta/superpowers/specs/2026-09-08-primer-detect-design.md for the state +# machine this ports. +# +# All decision logic lives here, not in the .sh wrapper — no I/O, so this +# is directly fixture-testable with synthetic strings (see the smoke test). +# The trigger chain is evaluated by threading each trigger's effect +# forward into the fact the next trigger reads (PROJ_OI, PROJ_BL below), +# not by writing out "OR about to become true" disjunctions per trigger — +# see the spec's "Why threading, not disjunctions" note for why the naive +# approach doesn't compose past one chained link. + +def has_inline_outstanding: + test("(?m)^## Outstanding items"); + +# jq/Oniguruma's "m" flag makes "." match newlines (the "s" flag means +# something else here -- single-line anchor mode -- unlike PCRE, where +# the letters are swapped). Without "m", .*? can never cross the log +# block's internal newlines and this always fails to match. +def log_drift($primer_exists; $actual_log; $primer_content): + if $primer_exists == 0 then 0 + else + (($primer_content | capture("Current `git log --oneline -5`[^`]*```\\n(?<block>.*?)```"; "m")) // null | .block) as $recorded + | if $recorded == null then 1 + elif ($recorded | gsub("^\\s+|\\s+$";"")) == ($actual_log | gsub("^\\s+|\\s+$";"")) then 0 + else 1 + end + end; + +def is_allowlisted: + (startswith("docs/") or startswith(".session-continuity/")) as $dir_ok + | (split("/") | .[-1]) as $base + | ($base | test("^(README|CHANGELOG|LICENSE)")) as $name_ok + | ($dir_ok or $name_ok); + +def code_staged($files): + ($files | split("\n") | map(select(length > 0))) as $paths + | ($paths | any(is_allowlisted | not)); + +def github_origin($origin): + $origin | test("github\\.com"); + +($primer_content | has_inline_outstanding) as $INLINE +| (log_drift($primer_exists; $git_log; $primer_content)) as $DRIFT +| (code_staged($staged_files)) as $STAGED +| (github_origin($origin_url)) as $GH + +| ($project_context_exists == 0) as $DO_SPLIT +| ($INLINE and ($outstanding_items_exists == 0)) as $DO_OSPLIT +| (if $DO_OSPLIT then 1 else $outstanding_items_exists end) as $PROJ_OI +| ($PROJ_OI == 1 and $backlog_exists == 0) as $DO_BRENAME +| (if $DO_BRENAME then 1 else $backlog_exists end) as $PROJ_BL +| ($PROJ_BL == 1 and $GH) as $DO_B2I +| ($DRIFT == 1 or $STAGED) as $DO_REFRESH + +| ([] + | if $DO_SPLIT then . + ["split"] else . end + | if $DO_OSPLIT then . + ["outstanding_split"] else . end + | if $DO_BRENAME then . + ["backlog_rename"] else . end + | if $DO_B2I then . + ["backlog_to_issues"] else . end + | if $DO_REFRESH then . + ["refresh"] else . end + ) as $triggered_steps +| (if $primer_exists == 0 then ["init"] else $triggered_steps end) as $steps + +| ("PRIMER_EXISTS=" + ($primer_exists|tostring)), + ("LEARNINGS_EXISTS=" + ($learnings_exists|tostring)), + ("PROJECT_CONTEXT_EXISTS=" + ($project_context_exists|tostring)), + ("OUTSTANDING_ITEMS_EXISTS=" + ($outstanding_items_exists|tostring)), + ("PRIMER_HAS_INLINE_OUTSTANDING=" + (if $INLINE then "1" else "0" end)), + ("BACKLOG_EXISTS=" + ($backlog_exists|tostring)), + ("ROADMAP_EXISTS=" + ($roadmap_exists|tostring)), + ("GITHUB_ORIGIN=" + (if $GH then "1" else "0" end)), + ("LOG_DRIFT=" + ($DRIFT|tostring)), + ("CODE_STAGED=" + (if $STAGED then "1" else "0" end)), + ("STEPS=" + ($steps | join(","))) diff --git a/hooks/lib/primer-detect.sh b/hooks/lib/primer-detect.sh new file mode 100755 index 0000000..369881d --- /dev/null +++ b/hooks/lib/primer-detect.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/primer-detect.sh — dispatch decision for /session-continuity:primer. +# See meta/superpowers/specs/2026-09-08-primer-detect-design.md for the full +# state machine this ports (unchanged behavior, just executable instead of +# hand-evaluated per invocation) and +# meta/superpowers/plans/2026-09-08-primer-detect.md for the implementation +# plan. +# +# Usage: primer-detect.sh [<project-dir>] (default: .) +# Prints KEY=value lines to stdout on success, ending in +# STEPS=<comma,separated,ordered,list> (possibly empty — empty means check +# mode, primer is current and no migration triggers fired): +# PRIMER_EXISTS=0|1 LEARNINGS_EXISTS=0|1 +# PROJECT_CONTEXT_EXISTS=0|1 OUTSTANDING_ITEMS_EXISTS=0|1 +# PRIMER_HAS_INLINE_OUTSTANDING=0|1 BACKLOG_EXISTS=0|1 +# ROADMAP_EXISTS=0|1 GITHUB_ORIGIN=0|1 +# LOG_DRIFT=0|1 CODE_STAGED=0|1 +# STEPS=<split,outstanding_split,backlog_rename,backlog_to_issues,refresh,init> +# +# Operational failure (jq missing, primer-detect.jq missing or from a +# different CONTRACT_VERSION, <project-dir> not inside a git repository) +# prints one diagnostic line to stderr and exits 1 with NO STEPS= line on +# stdout at all — no conservative default dispatch. Some STEPS values gate +# destructive migrations (git mv/git rm in Steps 3c/3d), so guessing wrong +# on failure is worse than stopping; the caller must treat a missing +# STEPS= line as a hard stop, not degrade to any default step list. + +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JQ_FILTER="$SCRIPT_DIR/primer-detect.jq" +DIR="${1:-.}" + +die() { # <message> + printf 'primer-detect.sh: %s\n' "$1" >&2 + exit 1 +} + +command -v jq >/dev/null 2>&1 \ + || die "jq is not installed, so the primer dispatch cannot be computed." +[[ -r "$JQ_FILTER" ]] \ + || die "primer-detect.jq is missing from $SCRIPT_DIR — the plugin cache is incomplete. Run \`/session-continuity:update\`." +grep -q '^# CONTRACT_VERSION=1$' "$JQ_FILTER" \ + || die "primer-detect.jq is from a different plugin version — run \`/session-continuity:update\`." +git -C "$DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1 \ + || die "$DIR is not inside a git repository." + +file_flag() { # <path relative to $DIR> -> 1|0 + [[ -f "$DIR/$1" ]] && echo 1 || echo 0 +} + +PRIMER_EXISTS="$(file_flag .session-continuity/SESSION_PRIMER.md)" +LEARNINGS_EXISTS="$(file_flag .session-continuity/LEARNINGS.md)" +PROJECT_CONTEXT_EXISTS="$(file_flag .session-continuity/PROJECT_CONTEXT.md)" +OUTSTANDING_ITEMS_EXISTS="$(file_flag .session-continuity/OUTSTANDING_ITEMS.md)" +BACKLOG_EXISTS="$(file_flag .session-continuity/BACKLOG.md)" +ROADMAP_EXISTS="$(file_flag .session-continuity/ROADMAP.md)" + +PRIMER_CONTENT="" +[[ "$PRIMER_EXISTS" == "1" ]] && PRIMER_CONTENT="$(cat "$DIR/.session-continuity/SESSION_PRIMER.md")" + +ORIGIN_URL="$(git -C "$DIR" remote get-url origin 2>/dev/null || true)" +GIT_LOG="$(git -C "$DIR" log --oneline -5 2>/dev/null || true)" +STAGED_FILES="$(git -C "$DIR" diff --cached --name-only 2>/dev/null || true)" + +ERRFILE="$(mktemp)" +RESULT="$( + jq -r -n \ + --argjson primer_exists "$PRIMER_EXISTS" \ + --argjson learnings_exists "$LEARNINGS_EXISTS" \ + --argjson project_context_exists "$PROJECT_CONTEXT_EXISTS" \ + --argjson outstanding_items_exists "$OUTSTANDING_ITEMS_EXISTS" \ + --argjson backlog_exists "$BACKLOG_EXISTS" \ + --argjson roadmap_exists "$ROADMAP_EXISTS" \ + --arg origin_url "$ORIGIN_URL" \ + --arg git_log "$GIT_LOG" \ + --arg staged_files "$STAGED_FILES" \ + --arg primer_content "$PRIMER_CONTENT" \ + -f "$JQ_FILTER" 2>"$ERRFILE" +)" +JQ_STATUS=$? +DETAIL="$(head -1 "$ERRFILE" 2>/dev/null)" +rm -f "$ERRFILE" + +if [[ "$JQ_STATUS" -ne 0 || -z "$RESULT" ]]; then + die "the detect filter failed: ${DETAIL:-jq exited $JQ_STATUS}" +fi + +printf '%s\n' "$RESULT" diff --git a/meta/superpowers/plans/2026-09-08-primer-detect.md b/meta/superpowers/plans/2026-09-08-primer-detect.md new file mode 100644 index 0000000..4c7865d --- /dev/null +++ b/meta/superpowers/plans/2026-09-08-primer-detect.md @@ -0,0 +1,718 @@ +# Determinism Phase 6, sub-project A — `primer-detect.sh`/`.jq` Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace `commands/primer.md` Step 1's hand-evaluated 4-state-plus-3-trigger dispatch logic (~15 lines of nested-conditional prose, including a sequencing rule easy to misapply) with one script, `hooks/lib/primer-detect.sh`, that gathers the same raw facts already gathered today and prints a definitive, ordered `STEPS=` list telling the model exactly which of Steps 2/3/3b/3c/3d/4/5 to run. + +**Architecture:** `primer-detect.sh` (bash, I/O only — file-existence checks, three git commands, one file read) pipes everything into `primer-detect.jq` (pure decision function, no I/O, fixture-testable with synthetic strings). The `.jq` filter evaluates each migration trigger by **threading each trigger's effect forward** into the fact the next trigger reads (a chained `outstanding_split → backlog_rename → backlog_to_issues` dependency), not by writing out "OR about to become true" disjunctions per trigger — that approach was tried, found not to compose past one link, and replaced during this plan's own verification pass (see Task 1's notes). `commands/primer.md` Step 1 shrinks to one script call plus a lookup table from `STEPS` names to step numbers. + +**Tech Stack:** Bash, `jq` (already a hard dependency across this plugin), zsh (smoke tests only). + +**Spec:** `meta/superpowers/specs/2026-09-08-primer-detect-design.md`. That spec was corrected twice during writing (caveman-review, then this plan's own implementation-first verification) — both fixes are already folded into the spec text; this plan implements the spec as it now reads, no further corrections needed. + +## Global Constraints + +- `primer-detect.sh` carries a `# CONTRACT_VERSION=1` header (both the `.sh` and the `.jq`) and is called through `require_script` from `commands/primer.md`, exactly like `primer-status.sh` already is in Step 5. +- **No conservative default dispatch on failure.** Unlike `token-overlap.sh` (empty output safely degrades to "zero matches"), `primer-detect.sh` prints no `STEPS=` line at all on any operational failure and exits nonzero — some `STEPS` values gate destructive migrations (`git mv`/`git rm`), so guessing wrong is worse than stopping. `commands/primer.md` must treat a missing `STEPS=` line as a hard stop. +- **Never invent a value.** Every fact the script cannot resolve reflects reality (a missing file is `0`, not a guess) — this plan changes *how* the dispatch decision is computed, never *what* Steps 2/3/3b/3c/3d/4/5 themselves do. +- All decision logic lives in `primer-detect.jq`, none in `primer-detect.sh` — the `.sh` wrapper's only job is gathering raw facts and invoking the filter, mirroring `token-overlap.sh`/`candidate-extract.sh`. +- Do not touch Steps 2, 3, 3b, 3c, 3d, 4, or 5's own internal logic — this plan scripts *whether* they run, not *what* they do once entered. (Their own mechanics are sub-projects B/C/D per the spec's Context section — out of scope here.) +- Do not touch `candidate-extract.jq`'s `overlap()` (issue #40, already fixed and closed in a prior session) or `hooks/lib/token-overlap.sh`/`.jq` (issue #42, already shipped) — unrelated to this plan. + +--- + +## File Structure + +| File | Responsibility | +|---|---| +| `hooks/lib/primer-detect.jq` (new) | Pure decision function: takes the raw facts as string/int arguments, runs the state machine, prints `KEY=value` lines ending in `STEPS=`. No I/O. | +| `hooks/lib/primer-detect.sh` (new) | Thin I/O wrapper: file-existence checks, `git remote get-url origin`, `git log --oneline -5`, `git diff --cached --name-only`, reads the primer file if present, invokes the filter. | +| `commands/primer.md` (modified) | Step 1 collapses to one script call plus a `STEPS`-name-to-step-number table. Steps 3b/3c/3d's opening "Runs whenever ..." sentences are simplified to "Runs when `<name>` appears in Step 1's `STEPS`" — restating the old boolean conditions in prose would now be actively misleading, since the corrected threaded logic lives only in the `.jq` filter. | +| `meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh` (new) | Smoke test: 16 assertions total (real scratch git repos, no mocking) — the 11 state-machine fixtures, a `5b` docs-allowlist variant, and 4 operational-failure cases. | +| `meta/superpowers/specs/2026-09-02-determinism-program-design.md` (modified) | Phase 6 entry notes sub-project A shipped, points to this plan; sub-projects B–E remain listed as pending. | +| `CHANGELOG.md` (modified) | New version entry. | +| `.claude-plugin/plugin.json` (modified) | Version bump. | + +--- + +### Task 1: `hooks/lib/primer-detect.jq` + `hooks/lib/primer-detect.sh` + +**Files:** +- Create: `hooks/lib/primer-detect.jq` +- Create: `hooks/lib/primer-detect.sh` +- Test: `meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh` + +**Interfaces:** +- Produces: `bash primer-detect.sh [<project-dir>]` (default `.`). Prints `KEY=value` lines to stdout, ending in `STEPS=<comma,separated,ordered,list>` (possibly empty). Exits 0 on success. On operational failure (jq missing, filter missing/wrong version, `<project-dir>` not a git repo), prints one diagnostic line to stderr and exits 1 with **no** `STEPS=` line anywhere in stdout. +- Consumes: `jq` (hard dependency), `git`. + +**A note on the log-drift fixture design (read before writing tests):** `primer-detect.sh` reads `SESSION_PRIMER.md` from the *working tree*, not from a git commit — so a fixture that wants "recorded log block matches actual `git log`" never needs the primer file's own content to be committed at all. Write the primer file to disk with whatever recorded block you want *after* whatever commits the fixture needs, and leave it uncommitted. There is no way to make a *committed* primer file accurately quote the `git log` of the very commit that adds it (the commit's own hash isn't known until after committing) — this is an inherent property of any git-log-embedding scheme, not a bug this plan introduces or needs to solve, and the real command's Step 4 (`refresh mode`) only ever *stages* the primer, never commits it itself, for exactly this reason. + +**jq/Oniguruma flag note (also read before writing tests):** jq's regex flag letters don't match PCRE convention. `"s"` means *single-line anchor mode* (`^`/`$` match string start/end only); `"m"` is the flag that makes `.` match newlines. A regex built assuming PCRE's `s` (dotall) will silently fail to match multi-line content and must use `"m"` instead. + +- [ ] **Step 1: Write the failing smoke test** + +Create `meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh`: + +```zsh +#!/usr/bin/env zsh +# primer-detect.sh/.jq smoke test. Hermetic: one scratch git repo per case, +# built fresh via mk_repo. No mocking needed -- every fact is a real file +# or a real git command against a real (throwaway) repository. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +tool="$lib/primer-detect.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +# mk_repo <dir> <split:0|1> <oi_file:0|1> <bl_file:0|1> <inline:0|1> <origin:gh|other> <staged:none|code|docs> +# Builds a fresh scratch repo with .session-continuity/ populated per the +# flags, commits everything, then writes SESSION_PRIMER.md's log block to +# exactly match the post-commit `git log --oneline -5` (never re-committed +# afterward -- see this plan's Task 1 notes on why that avoids a +# self-referential-hash problem). Callers that want DRIFT instead +# overwrite the block themselves after calling mk_repo. +mk_repo() { + local dir="$1" split=$2 oi=$3 bl=$4 inline=$5 origin=$6 staged=$7 + rm -rf "$dir" + mkdir -p "$dir/.session-continuity" + git -C "$dir" init -q + git -C "$dir" config user.email test@example.com + git -C "$dir" config user.name Test + if [[ "$origin" == "gh" ]]; then + git -C "$dir" remote add origin https://github.com/example/repo.git + else + git -C "$dir" remote add origin https://example.com/example/repo.git + fi + : > "$dir/.session-continuity/LEARNINGS.md" + (( split )) && : > "$dir/.session-continuity/PROJECT_CONTEXT.md" + : > "$dir/.session-continuity/ROADMAP.md" + (( oi )) && : > "$dir/.session-continuity/OUTSTANDING_ITEMS.md" + (( bl )) && : > "$dir/.session-continuity/BACKLOG.md" + local heading="" + (( inline )) && heading=$'## Outstanding items\n1. something\n\n' + print -r -- "${heading}# Primer + +placeholder body, overwritten below with the real log block +" > "$dir/.session-continuity/SESSION_PRIMER.md" + git -C "$dir" add -A + git -C "$dir" commit -qm init + local log + log="$(git -C "$dir" log --oneline -5)" + print -r -- "${heading}# Primer + +**Current \`git log --oneline -5\` (primary branch):** + +\`\`\` +$log +\`\`\` +" > "$dir/.session-continuity/SESSION_PRIMER.md" + case "$staged" in + code) print -r -- x > "$dir/src.js"; git -C "$dir" add src.js ;; + docs) print -r -- x >> "$dir/.session-continuity/LEARNINGS.md"; git -C "$dir" add .session-continuity/LEARNINGS.md ;; + esac +} + +steps_of() { bash "$tool" "$1" | awk -F= '/^STEPS=/{print $2}'; } + +# --- 1: fresh install (no .session-continuity/ at all) -> init ------------- +d="$work/case1"; mkdir -p "$d" +git -C "$d" init -q; git -C "$d" config user.email t@t.com; git -C "$d" config user.name T +: > "$d/README.md"; git -C "$d" add -A; git -C "$d" commit -qm init +git -C "$d" remote add origin https://github.com/example/repo.git +[[ "$(steps_of "$d")" == "init" ]] && ok "1: fresh install -> init" || bad "1: got '$(steps_of "$d")'" + +# --- 2: existing unsplit primer, otherwise current -> split ----------------- +d="$work/case2"; mk_repo "$d" 0 0 1 0 other none +[[ "$(steps_of "$d")" == "split" ]] && ok "2: unsplit only -> split" || bad "2: got '$(steps_of "$d")'" + +# --- 3: split + current + clean -> empty ------------------------------------ +d="$work/case3"; mk_repo "$d" 1 0 1 0 other none +[[ "$(steps_of "$d")" == "" ]] && ok "3: split+current+clean -> empty" || bad "3: got '$(steps_of "$d")'" + +# --- 4: recorded log block differs from actual -> refresh ------------------- +d="$work/case4"; mk_repo "$d" 1 0 1 0 other none +print -r -- "# Primer + +**Current \`git log --oneline -5\` (primary branch):** + +\`\`\` +0000000 stale placeholder +\`\`\` +" > "$d/.session-continuity/SESSION_PRIMER.md" +[[ "$(steps_of "$d")" == "refresh" ]] && ok "4: log drift -> refresh" || bad "4: got '$(steps_of "$d")'" + +# --- 5: non-allowlisted file staged -> refresh ------------------------------- +d="$work/case5"; mk_repo "$d" 1 0 1 0 other code +[[ "$(steps_of "$d")" == "refresh" ]] && ok "5: non-allowlisted staged -> refresh" || bad "5: got '$(steps_of "$d")'" + +# --- docs-only staged -> NOT refresh (allowlisted) -------------------------- +d="$work/case5b"; mk_repo "$d" 1 0 1 0 other docs +[[ "$(steps_of "$d")" == "" ]] && ok "5b: docs-only staged -> no refresh (allowlisted)" || bad "5b: got '$(steps_of "$d")'" + +# --- 6: inline heading, no OUTSTANDING_ITEMS.md -> outstanding_split ------- +d="$work/case6"; mk_repo "$d" 1 0 1 1 other none +[[ "$(steps_of "$d")" == "outstanding_split" ]] && ok "6: inline+no file -> outstanding_split" || bad "6: got '$(steps_of "$d")'" + +# --- 7: both unsplit AND inline -> split,outstanding_split (order) --------- +d="$work/case7"; mk_repo "$d" 0 0 1 1 other none +[[ "$(steps_of "$d")" == "split,outstanding_split" ]] && ok "7: unsplit+inline -> split,outstanding_split in order" || bad "7: got '$(steps_of "$d")'" + +# --- 8: OUTSTANDING_ITEMS.md exists, no BACKLOG.md -> backlog_rename ------- +d="$work/case8"; mk_repo "$d" 1 1 0 0 other none +[[ "$(steps_of "$d")" == "backlog_rename" ]] && ok "8: outstanding file, no backlog -> backlog_rename" || bad "8: got '$(steps_of "$d")'" + +# --- 9: BACKLOG.md exists, github origin -> backlog_to_issues -------------- +d="$work/case9"; mk_repo "$d" 1 0 1 0 gh none +[[ "$(steps_of "$d")" == "backlog_to_issues" ]] && ok "9: backlog exists, github -> backlog_to_issues" || bad "9: got '$(steps_of "$d")'" + +# --- 10: BACKLOG.md exists, non-github origin -> empty (fossil, no GH call) - +d="$work/case10"; mk_repo "$d" 1 0 1 0 other none +[[ "$(steps_of "$d")" == "" ]] && ok "10: backlog exists, non-github -> empty (fossil)" || bad "10: got '$(steps_of "$d")'" + +# --- 11: full worst-case stack, exact order --------------------------------- +d="$work/case11"; mk_repo "$d" 0 0 0 1 gh none +[[ "$(steps_of "$d")" == "split,outstanding_split,backlog_rename,backlog_to_issues" ]] \ + && ok "11: full stack fires in dependency order" || bad "11: got '$(steps_of "$d")'" + +# --- 12: operational failure -- missing filter, no STEPS line at all ------- +badlib="$work/badlib"; mkdir -p "$badlib" +cp "$lib/primer-detect.sh" "$badlib/" +out="$(bash "$badlib/primer-detect.sh" "$work/case3" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "12: missing filter -> nonzero exit, no STEPS= line" || bad "12: rc=$rc out='$out'" + +# --- 13: operational failure -- not a git repo ------------------------------ +notgit="$work/notgit"; mkdir -p "$notgit" +out="$(bash "$tool" "$notgit" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "13: not a git repo -> nonzero exit, no STEPS= line" || bad "13: rc=$rc out='$out'" + +# --- 14: operational failure -- wrong CONTRACT_VERSION ----------------------- +wronglib="$work/wronglib"; mkdir -p "$wronglib" +cp "$lib/primer-detect.sh" "$wronglib/" +sed 's/CONTRACT_VERSION=1/CONTRACT_VERSION=99/' "$lib/primer-detect.jq" > "$wronglib/primer-detect.jq" +out="$(bash "$wronglib/primer-detect.sh" "$work/case3" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "14: wrong CONTRACT_VERSION -> nonzero exit, no STEPS= line" || bad "14: rc=$rc out='$out'" + +# --- 15: operational failure -- jq absent from PATH ------------------------- +nojq="$work/nojq"; mkdir -p "$nojq/bin" +for b in bash git awk grep sed head cat mktemp dirname; do + p="$(command -v "$b")"; [[ -n "$p" ]] && ln -sf "$p" "$nojq/bin/$b" +done +out="$(PATH="$nojq/bin" bash "$tool" "$work/case3" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "15: jq absent from PATH -> nonzero exit, no STEPS= line" || bad "15: rc=$rc out='$out'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) +``` + +- [ ] **Step 2: Run it to verify it fails** + +```bash +chmod +x meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh +zsh meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh +``` + +Expected: FAIL on every assertion — `hooks/lib/primer-detect.sh` does not exist yet. + +- [ ] **Step 3: Write `hooks/lib/primer-detect.jq`** + +```jq +# CONTRACT_VERSION=1 +# hooks/lib/primer-detect.jq — /session-continuity:primer dispatch decision. +# Invoked via primer-detect.sh; see that file for the CLI contract and +# meta/superpowers/specs/2026-09-08-primer-detect-design.md for the state +# machine this ports. +# +# All decision logic lives here, not in the .sh wrapper — no I/O, so this +# is directly fixture-testable with synthetic strings (see the smoke test). +# The trigger chain is evaluated by threading each trigger's effect +# forward into the fact the next trigger reads (PROJ_OI, PROJ_BL below), +# not by writing out "OR about to become true" disjunctions per trigger — +# see the spec's "Why threading, not disjunctions" note for why the naive +# approach doesn't compose past one chained link. + +def has_inline_outstanding: + test("(?m)^## Outstanding items"); + +# jq/Oniguruma's "m" flag makes "." match newlines (the "s" flag means +# something else here -- single-line anchor mode -- unlike PCRE, where +# the letters are swapped). Without "m", .*? can never cross the log +# block's internal newlines and this always fails to match. +def log_drift($primer_exists; $actual_log; $primer_content): + if $primer_exists == 0 then 0 + else + (($primer_content | capture("Current `git log --oneline -5`[^`]*```\\n(?<block>.*?)```"; "m")) // null | .block) as $recorded + | if $recorded == null then 1 + elif ($recorded | gsub("^\\s+|\\s+$";"")) == ($actual_log | gsub("^\\s+|\\s+$";"")) then 0 + else 1 + end + end; + +def is_allowlisted: + (startswith("docs/") or startswith(".session-continuity/")) as $dir_ok + | (split("/") | .[-1]) as $base + | ($base | test("^(README|CHANGELOG|LICENSE)")) as $name_ok + | ($dir_ok or $name_ok); + +def code_staged($files): + ($files | split("\n") | map(select(length > 0))) as $paths + | ($paths | any(is_allowlisted | not)); + +def github_origin($origin): + $origin | test("github\\.com"); + +($primer_content | has_inline_outstanding) as $INLINE +| (log_drift($primer_exists; $git_log; $primer_content)) as $DRIFT +| (code_staged($staged_files)) as $STAGED +| (github_origin($origin_url)) as $GH + +| ($project_context_exists == 0) as $DO_SPLIT +| ($INLINE and ($outstanding_items_exists == 0)) as $DO_OSPLIT +| (if $DO_OSPLIT then 1 else $outstanding_items_exists end) as $PROJ_OI +| ($PROJ_OI == 1 and $backlog_exists == 0) as $DO_BRENAME +| (if $DO_BRENAME then 1 else $backlog_exists end) as $PROJ_BL +| ($PROJ_BL == 1 and $GH) as $DO_B2I +| ($DRIFT == 1 or $STAGED) as $DO_REFRESH + +| ([] + | if $DO_SPLIT then . + ["split"] else . end + | if $DO_OSPLIT then . + ["outstanding_split"] else . end + | if $DO_BRENAME then . + ["backlog_rename"] else . end + | if $DO_B2I then . + ["backlog_to_issues"] else . end + | if $DO_REFRESH then . + ["refresh"] else . end + ) as $triggered_steps +| (if $primer_exists == 0 then ["init"] else $triggered_steps end) as $steps + +| ("PRIMER_EXISTS=" + ($primer_exists|tostring)), + ("LEARNINGS_EXISTS=" + ($learnings_exists|tostring)), + ("PROJECT_CONTEXT_EXISTS=" + ($project_context_exists|tostring)), + ("OUTSTANDING_ITEMS_EXISTS=" + ($outstanding_items_exists|tostring)), + ("PRIMER_HAS_INLINE_OUTSTANDING=" + (if $INLINE then "1" else "0" end)), + ("BACKLOG_EXISTS=" + ($backlog_exists|tostring)), + ("ROADMAP_EXISTS=" + ($roadmap_exists|tostring)), + ("GITHUB_ORIGIN=" + (if $GH then "1" else "0" end)), + ("LOG_DRIFT=" + ($DRIFT|tostring)), + ("CODE_STAGED=" + (if $STAGED then "1" else "0" end)), + ("STEPS=" + ($steps | join(","))) +``` + +- [ ] **Step 4: Write `hooks/lib/primer-detect.sh`** + +```bash +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/primer-detect.sh — dispatch decision for /session-continuity:primer. +# See meta/superpowers/specs/2026-09-08-primer-detect-design.md for the full +# state machine this ports (unchanged behavior, just executable instead of +# hand-evaluated per invocation) and +# meta/superpowers/plans/2026-09-08-primer-detect.md for the implementation +# plan. +# +# Usage: primer-detect.sh [<project-dir>] (default: .) +# Prints KEY=value lines to stdout on success, ending in +# STEPS=<comma,separated,ordered,list> (possibly empty — empty means check +# mode, primer is current and no migration triggers fired): +# PRIMER_EXISTS=0|1 LEARNINGS_EXISTS=0|1 +# PROJECT_CONTEXT_EXISTS=0|1 OUTSTANDING_ITEMS_EXISTS=0|1 +# PRIMER_HAS_INLINE_OUTSTANDING=0|1 BACKLOG_EXISTS=0|1 +# ROADMAP_EXISTS=0|1 GITHUB_ORIGIN=0|1 +# LOG_DRIFT=0|1 CODE_STAGED=0|1 +# STEPS=<split,outstanding_split,backlog_rename,backlog_to_issues,refresh,init> +# +# Operational failure (jq missing, primer-detect.jq missing or from a +# different CONTRACT_VERSION, <project-dir> not inside a git repository) +# prints one diagnostic line to stderr and exits 1 with NO STEPS= line on +# stdout at all — no conservative default dispatch. Some STEPS values gate +# destructive migrations (git mv/git rm in Steps 3c/3d), so guessing wrong +# on failure is worse than stopping; the caller must treat a missing +# STEPS= line as a hard stop, not degrade to any default step list. + +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JQ_FILTER="$SCRIPT_DIR/primer-detect.jq" +DIR="${1:-.}" + +die() { # <message> + printf 'primer-detect.sh: %s\n' "$1" >&2 + exit 1 +} + +command -v jq >/dev/null 2>&1 \ + || die "jq is not installed, so the primer dispatch cannot be computed." +[[ -r "$JQ_FILTER" ]] \ + || die "primer-detect.jq is missing from $SCRIPT_DIR — the plugin cache is incomplete. Run \`/session-continuity:update\`." +grep -q '^# CONTRACT_VERSION=1$' "$JQ_FILTER" \ + || die "primer-detect.jq is from a different plugin version — run \`/session-continuity:update\`." +git -C "$DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1 \ + || die "$DIR is not inside a git repository." + +file_flag() { # <path relative to $DIR> -> 1|0 + [[ -f "$DIR/$1" ]] && echo 1 || echo 0 +} + +PRIMER_EXISTS="$(file_flag .session-continuity/SESSION_PRIMER.md)" +LEARNINGS_EXISTS="$(file_flag .session-continuity/LEARNINGS.md)" +PROJECT_CONTEXT_EXISTS="$(file_flag .session-continuity/PROJECT_CONTEXT.md)" +OUTSTANDING_ITEMS_EXISTS="$(file_flag .session-continuity/OUTSTANDING_ITEMS.md)" +BACKLOG_EXISTS="$(file_flag .session-continuity/BACKLOG.md)" +ROADMAP_EXISTS="$(file_flag .session-continuity/ROADMAP.md)" + +PRIMER_CONTENT="" +[[ "$PRIMER_EXISTS" == "1" ]] && PRIMER_CONTENT="$(cat "$DIR/.session-continuity/SESSION_PRIMER.md")" + +ORIGIN_URL="$(git -C "$DIR" remote get-url origin 2>/dev/null || true)" +GIT_LOG="$(git -C "$DIR" log --oneline -5 2>/dev/null || true)" +STAGED_FILES="$(git -C "$DIR" diff --cached --name-only 2>/dev/null || true)" + +ERRFILE="$(mktemp)" +RESULT="$( + jq -r -n \ + --argjson primer_exists "$PRIMER_EXISTS" \ + --argjson learnings_exists "$LEARNINGS_EXISTS" \ + --argjson project_context_exists "$PROJECT_CONTEXT_EXISTS" \ + --argjson outstanding_items_exists "$OUTSTANDING_ITEMS_EXISTS" \ + --argjson backlog_exists "$BACKLOG_EXISTS" \ + --argjson roadmap_exists "$ROADMAP_EXISTS" \ + --arg origin_url "$ORIGIN_URL" \ + --arg git_log "$GIT_LOG" \ + --arg staged_files "$STAGED_FILES" \ + --arg primer_content "$PRIMER_CONTENT" \ + -f "$JQ_FILTER" 2>"$ERRFILE" +)" +JQ_STATUS=$? +DETAIL="$(head -1 "$ERRFILE" 2>/dev/null)" +rm -f "$ERRFILE" + +if [[ "$JQ_STATUS" -ne 0 || -z "$RESULT" ]]; then + die "the detect filter failed: ${DETAIL:-jq exited $JQ_STATUS}" +fi + +printf '%s\n' "$RESULT" +``` + +```bash +chmod +x hooks/lib/primer-detect.sh +``` + +- [ ] **Step 5: Run the smoke test to verify all assertions pass** + +```bash +zsh meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh +``` + +Expected: `Result: 16 passed, 0 failed`. + +- [ ] **Step 6: Commit** + +```bash +git add hooks/lib/primer-detect.jq hooks/lib/primer-detect.sh meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh +git commit -m "feat: add primer-detect.sh/.jq, scripting /session-continuity:primer's dispatch decision" +``` + +--- + +### Task 2: `commands/primer.md` — call the script + +**Files:** +- Modify: `commands/primer.md` (Step 1, currently lines 11-64; Steps 3b/3c/3d's opening sentences) + +**Interfaces:** +- Consumes: `hooks/lib/primer-detect.sh` (Task 1), resolved via `CLAUDE_PLUGIN_ROOT` and `require_script`, exactly like `primer-status.sh` already is in Step 5. + +- [ ] **Step 1: Replace Step 1 in full** + +Using the Edit tool, replace this exact block (currently `commands/primer.md` lines 11-64, from `## Step 1 — Detect state` through the line ending `...run Step 3d (markdown backlog → GitHub Issues) after 3c.`): + +````markdown +## Step 1 — Detect state + +Gather the raw data for every check below in **one Bash call**, timed: + +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +[ -f .session-continuity/SESSION_PRIMER.md ] && echo "PRIMER_EXISTS=1" || echo "PRIMER_EXISTS=0" +[ -f .session-continuity/LEARNINGS.md ] && echo "LEARNINGS_EXISTS=1" || echo "LEARNINGS_EXISTS=0" +[ -f .session-continuity/PROJECT_CONTEXT.md ] && echo "PROJECT_CONTEXT_EXISTS=1" || echo "PROJECT_CONTEXT_EXISTS=0" +[ -f .session-continuity/OUTSTANDING_ITEMS.md ] && echo "OUTSTANDING_ITEMS_EXISTS=1" || echo "OUTSTANDING_ITEMS_EXISTS=0" +grep -q '^## Outstanding items' .session-continuity/SESSION_PRIMER.md 2>/dev/null && echo "PRIMER_HAS_INLINE_OUTSTANDING=1" || echo "PRIMER_HAS_INLINE_OUTSTANDING=0" +[ -f .session-continuity/BACKLOG.md ] && echo "BACKLOG_EXISTS=1" || echo "BACKLOG_EXISTS=0" +[ -f .session-continuity/ROADMAP.md ] && echo "ROADMAP_EXISTS=1" || echo "ROADMAP_EXISTS=0" +git remote get-url origin 2>/dev/null || echo "NO_ORIGIN" +git log --oneline -5 +git diff --cached --name-only +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-1-detect-state --duration="$_PERF_DURATION" +``` + +Interpret the output: + +1. Do `.session-continuity/SESSION_PRIMER.md` and `.session-continuity/LEARNINGS.md` exist? (`PRIMER_EXISTS` / `LEARNINGS_EXISTS` above.) +2. If a primer exists, does the `git log --oneline -5` block inside it match the `git log --oneline -5` output above? (mtime is intentionally not checked — formatters, save-on-blur, and `cat | tee` all bump mtime without changing content. The log-block diff is the authoritative drift signal.) +3. Does the `git diff --cached --name-only` output above contain any file outside `docs/`, `.session-continuity/`, `README*`, `CHANGELOG*`, `LICENSE*`? (Code is staged and a commit is imminent — the primer will be stale the moment that commit lands.) +4. If a primer exists, does `.session-continuity/PROJECT_CONTEXT.md` also exist? (`PROJECT_CONTEXT_EXISTS` above.) + +Four states result: + +- **No primer** → init mode (Step 2) +- **Primer exists but unsplit** (no `PROJECT_CONTEXT.md` yet) → split mode (Step 3) +- **Primer exists but stale** (log block drifted or code staged for commit) → refresh mode (Step 4) +- **Primer exists and current** (nothing staged) → check mode (Step 5) + +If `PRIMER_HAS_INLINE_OUTSTANDING=1` AND `OUTSTANDING_ITEMS_EXISTS=0`, +outstanding-items migration is needed — run it (Step 3b below) in addition +to whichever of the four states above applies. **Sequencing:** if the +primer is also unsplit (no `PROJECT_CONTEXT.md`), run the existing Split +mode (Step 3) to completion first, then run Step 3b against the resulting +primer, as two sequential edits — not simultaneous partitioning. The two +splits touch disjoint sections of the primer (stable-context headings vs. +the Outstanding items heading), so sequencing avoids any edit conflict. + +If `OUTSTANDING_ITEMS_EXISTS=1` AND `BACKLOG_EXISTS=0`, a file-rename +migration is needed — run it (Step 3c below) in addition to whichever of +the four states above applies. **Sequencing:** if Step 3b also fired this +run (inline heading present, no file yet), run Step 3b to completion +first — it still writes `OUTSTANDING_ITEMS.md` under the old name — then +run Step 3c against that result. Step 3c is strictly the one-level-up +file rename; it never inspects primer content. + +If `BACKLOG_EXISTS=1` (including after Step 3c) AND origin contains +`github.com`, run Step 3d (markdown backlog → GitHub Issues) after 3c. +```` + +with: + +````markdown +## Step 1 — Detect state + +Run the shared dispatch script once, timed: + +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-detect.sh" 1; then + DETECT_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-detect.sh" . 2>&1)" + DETECT_STATUS=$? +else + DETECT_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + DETECT_STATUS=1 +fi +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-1-detect-state --duration="$_PERF_DURATION" +echo "$DETECT_OUTPUT" +echo "DETECT_STATUS=$DETECT_STATUS" +``` + +**If `DETECT_STATUS` is nonzero, or `$DETECT_OUTPUT` has no `STEPS=` line: +stop.** Report `$DETECT_OUTPUT` to the user (it carries the diagnostic +either way — `require_script`'s message, or `primer-detect.sh`'s own +stderr, merged into stdout above) and do not execute any step below — +there is no safe default dispatch, since some steps run destructive +migrations (`git mv` in Step 3c, `git rm` in Step 3d). + +**Otherwise**, read `STEPS=` from `$DETECT_OUTPUT` and **execute every +name it lists, in the order given, then stop.** Do not re-derive which +steps should run from the individual `KEY=value` facts printed above +`STEPS=` — those are for transparency/debugging only, not a second +source of dispatch truth. An empty `STEPS=` means check mode: run Step 5. + +| Name in `STEPS` | Run | +|---|---| +| `init` | Step 2 (the only value `STEPS` can ever carry alone) | +| `split` | Step 3 | +| `outstanding_split` | Step 3b | +| `backlog_rename` | Step 3c | +| `backlog_to_issues` | Step 3d | +| `refresh` | Step 4 | +```` + +- [ ] **Step 2: Simplify Step 3b's opening sentence** + +Using the Edit tool, replace this exact block (currently `commands/primer.md`, the two sentences immediately under `## Step 3b — Outstanding-items split`): + +```markdown +Runs whenever `PRIMER_HAS_INLINE_OUTSTANDING=1` and +`OUTSTANDING_ITEMS_EXISTS=0` (see Step 1). Extract the primer's inline +`## Outstanding items` section into the new file; this is a one-time +content move, no numbering changes — the items keep whatever numbers +they currently have, and those become the first permanent IDs. +``` + +with: + +```markdown +Runs when `outstanding_split` appears in Step 1's `STEPS`. Extract the +primer's inline `## Outstanding items` section into the new file; this +is a one-time content move, no numbering changes — the items keep +whatever numbers they currently have, and those become the first +permanent IDs. +``` + +- [ ] **Step 3: Simplify Step 3c's opening sentence** + +Using the Edit tool, replace this exact block (currently `commands/primer.md`, the paragraph immediately under `## Step 3c — Backlog rename migration`): + +```markdown +Runs whenever `BACKLOG_EXISTS=0` AND `OUTSTANDING_ITEMS_EXISTS=1` (see +Step 1). This is strictly the `OUTSTANDING_ITEMS.md` → `BACKLOG.md` +rename, one level up from Step 3b (which may have just created +`OUTSTANDING_ITEMS.md` under its old name this same run — Step 3c runs +after it, per the sequencing note in Step 1). +``` + +with: + +```markdown +Runs when `backlog_rename` appears in Step 1's `STEPS`. This is strictly +the `OUTSTANDING_ITEMS.md` → `BACKLOG.md` rename, one level up from Step +3b (which may have just created `OUTSTANDING_ITEMS.md` under its old +name this same run — `STEPS` already places `backlog_rename` after +`outstanding_split` when both fire). +``` + +- [ ] **Step 4: Simplify Step 3d's opening sentence** + +Using the Edit tool, replace this exact block (currently `commands/primer.md`, the paragraph immediately under `## Step 3d — BACKLOG.md → GitHub Issues`): + +```markdown +Runs whenever `BACKLOG_EXISTS=1` (including after Step 3c just created +it) AND Step 1's origin URL contains `github.com`. If origin is missing +or not github.com, leave the file in place as a fossil and tell the +user `/session-continuity:doctor` will warn that the queue is inactive. +Do not keep writing to the fossil. +``` + +with: + +```markdown +Runs when `backlog_to_issues` appears in Step 1's `STEPS`. If it doesn't +(non-github origin, or no backlog to migrate), leave any existing +`BACKLOG.md` in place as a fossil and tell the user +`/session-continuity:doctor` will warn that the queue is inactive. Do +not keep writing to the fossil. +``` + +- [ ] **Step 5: Verify the old per-step condition restatements are gone** + +```bash +grep -c 'PRIMER_HAS_INLINE_OUTSTANDING=1.*and\|BACKLOG_EXISTS=0.*AND OUTSTANDING\|BACKLOG_EXISTS=1.*(including after Step 3c' commands/primer.md +``` + +Expected: `0` — the boolean conditions now live only in `primer-detect.jq`, referenced by `STEPS` membership everywhere else. + +- [ ] **Step 6: Commit** + +```bash +git add commands/primer.md +git commit -m "refactor: primer.md Step 1 dispatches via primer-detect.sh" +``` + +--- + +### Task 3: Doc pointers, regression pass, changelog + +**Files:** +- Modify: `meta/superpowers/specs/2026-09-02-determinism-program-design.md` +- Modify: `CHANGELOG.md` +- Modify: `.claude-plugin/plugin.json` + +- [ ] **Step 1: Update the design doc's Phase 6 entry** + +Using the Edit tool, replace this exact block in `meta/superpowers/specs/2026-09-02-determinism-program-design.md`: + +```markdown +**Phase 6 `#43` — `primer` detect, migrate, init, drift.** Mode detection plus +migration triggers (11-60, pure boolean logic over file existence); the +backlog rename migration (209-248, forty lines of prompt with no judgment in +any of its seven items, performing a destructive `git mv`); init-mode template +copy and mechanical placeholder substitution, collapsing the ten +`{{LATEST_COMMIT_*}}` slots into one `{{GIT_LOG_BLOCK}}`; and the drift check +plus test-count rerun with modal pinning (172-210, 249-250, 264-278). Largest +phase, lowest per-invocation frequency, highest blast radius — it runs a +`git mv` and rewrites five files. +``` + +with: + +```markdown +**Phase 6 `#43` — `primer` detect, migrate, init, drift.** Decomposed into +five sub-projects (see `meta/superpowers/specs/2026-09-08-primer-detect-design.md`'s +Context section for the full breakdown and why): **sub-project A shipped** +— Step 1's mode detection plus all three migration triggers, previously +hand-evaluated nested conditionals with an easy-to-miss sequencing rule, +now `hooks/lib/primer-detect.sh`/`.jq`. Plan: +`meta/superpowers/plans/2026-09-08-primer-detect.md`. Still pending: +sub-project B (Step 4's test-count majority-vote rerun — the same +compare-a-claimed-value-against-an-actual-one class Phase 7 is being +built to gate against), C (Step 3c/3d's `git mv`/`git rm` migration +mechanics themselves — sub-project A only scripted *whether* they run, +not *what* they do), D (Step 2's placeholder-derivation gather-and-regex), +E (Step 3/3b's section-bucketing judgment, lowest priority — near-zero +remaining audience, most judgment-heavy of the five). +``` + +- [ ] **Step 2: Full regression pass** + +```bash +for f in \ + meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh \ + meta/superpowers/validation/2026-09-08-token-overlap.md \ + meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh \ + meta/superpowers/validation/2026-08-17-perf-log-smoke.zsh \ + meta/superpowers/validation/2026-09-03-primer-status-smoke.zsh \ + meta/superpowers/validation/2026-08-12-session-start-smoke.zsh \ + meta/superpowers/validation/2026-09-01-require-script-smoke.zsh \ + meta/superpowers/validation/2026-09-07-backlog-issues-smoke.zsh \ + meta/superpowers/validation/2026-09-01-agent-active-smoke.zsh \ + meta/superpowers/validation/2026-09-02-resolve-transcript-smoke.zsh \ + meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh \ + meta/superpowers/validation/2026-09-02-candidate-render-smoke.zsh \ + meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh +do + [[ "$f" == *.zsh ]] || continue + echo "--- $f ---" + zsh "$f" || echo "FAILED: $f" +done +``` + +Expected: every runner ends `0 failed`. (`2026-09-08-token-overlap.md` in +the list above is a validation *log*, not a runner — included for +completeness of the "everything touched this program" review, nothing to +execute.) + +- [ ] **Step 3: Add a CHANGELOG entry** + +Add a new section at the top of `CHANGELOG.md`, directly under the `# Changelog` header and its description line, above the current top entry: + +```markdown +## [0.32.0] — 2026-09-08 + +### Changed +- **`/session-continuity:primer`'s Step 1 dispatch is now scripted.** New `hooks/lib/primer-detect.sh`/`.jq` replace ~15 lines of hand-evaluated nested-conditional prose (a 4-state classification plus 3 migration triggers with an easy-to-miss sequencing rule) with one script call that prints a definitive, ordered `STEPS=` list. The trigger chain is evaluated by threading each trigger's effect forward into the fact the next depends on (`outstanding_split → backlog_rename → backlog_to_issues`), not by re-deriving disjunctions per trigger — an approach tried and found not to compose past one chained link during this work. Determinism Phase 6 (#43) sub-project A; sub-projects B–E remain pending. +``` + +- [ ] **Step 4: Bump the plugin version** + +Using the Edit tool, update `.claude-plugin/plugin.json`'s `"version"` field from `"0.31.0"` to `"0.32.0"`. + +- [ ] **Step 5: Commit** + +```bash +git add meta/superpowers/specs/2026-09-02-determinism-program-design.md CHANGELOG.md .claude-plugin/plugin.json +git commit -m "docs: Phase 6 sub-project A doc pointers, changelog, and version bump" +``` diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index 303a7fa..d88083a 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -204,15 +204,20 @@ tokenize, drop short tokens and stopwords, intersect, threshold at 3 — computed once per `end-session` run, reused by both call sites. Set- intersection cardinality is a task models get wrong silently. -**Phase 6 `#43` — `primer` detect, migrate, init, drift.** Mode detection plus -migration triggers (11-60, pure boolean logic over file existence); the -backlog rename migration (209-248, forty lines of prompt with no judgment in -any of its seven items, performing a destructive `git mv`); init-mode template -copy and mechanical placeholder substitution, collapsing the ten -`{{LATEST_COMMIT_*}}` slots into one `{{GIT_LOG_BLOCK}}`; and the drift check -plus test-count rerun with modal pinning (172-210, 249-250, 264-278). Largest -phase, lowest per-invocation frequency, highest blast radius — it runs a -`git mv` and rewrites five files. +**Phase 6 `#43` — `primer` detect, migrate, init, drift.** Decomposed into +five sub-projects (see `meta/superpowers/specs/2026-09-08-primer-detect-design.md`'s +Context section for the full breakdown and why): **sub-project A shipped** +— Step 1's mode detection plus all three migration triggers, previously +hand-evaluated nested conditionals with an easy-to-miss sequencing rule, +now `hooks/lib/primer-detect.sh`/`.jq`. Plan: +`meta/superpowers/plans/2026-09-08-primer-detect.md`. Still pending: +sub-project B (Step 4's test-count majority-vote rerun — the same +compare-a-claimed-value-against-an-actual-one class Phase 7 is being +built to gate against), C (Step 3c/3d's `git mv`/`git rm` migration +mechanics themselves — sub-project A only scripted *whether* they run, +not *what* they do), D (Step 2's placeholder-derivation gather-and-regex), +E (Step 3/3b's section-bucketing judgment, lowest priority — near-zero +remaining audience, most judgment-heavy of the five). **Phase 7 `#44` — the gate that keeps it true.** A commit-time content gate on staged `commands/*.md` that blocks prompt text instructing a model to count, diff --git a/meta/superpowers/specs/2026-09-08-primer-detect-design.md b/meta/superpowers/specs/2026-09-08-primer-detect-design.md new file mode 100644 index 0000000..9c9d222 --- /dev/null +++ b/meta/superpowers/specs/2026-09-08-primer-detect-design.md @@ -0,0 +1,183 @@ +# Design — `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A) + +**Issue:** #43 (Determinism Phase 6 — `primer` detect, migrate, init, drift) + +## Context + +Phase 6's original scoping (`meta/superpowers/specs/2026-09-02-determinism-program-design.md`) +predates the GitHub Issues migration (2026-09-07), which added a fourth +migration step (`commands/primer.md` Step 3d, BACKLOG.md → GitHub Issues) +never mentioned in that entry. Re-reading `commands/primer.md` (372 lines, +8 steps) end to end found the phase decomposes into five independent +pieces, each mechanical-plus-judgment in different ratios: + +| Step | Frequency | Mechanical seam | Judgment that stays prose | +|---|---|---|---| +| 1 Detect state | every invocation | ~9 fact checks → dispatch decision | none | +| 2 Init mode | once per repo | placeholder derivation | ground rules, escalation steps | +| 3/3b Split modes | near-zero (pre-v0.13/v0.22) | section-name lookup, title extraction | overflow routing, unknown sections | +| 3c/3d Migrations | near-zero (pre-v0.29), destructive | `git mv`/`git rm` + rewrites | hex-tag-to-repo mapping | +| 4 Refresh mode | every drift-detected invocation | test-count majority-vote rerun | candidate-close judgment | + +This spec covers **only sub-project A: Step 1's detect/dispatch logic** — +the highest-frequency, zero-judgment piece. Sub-projects B (Step 4's +test-count rerun), C (3c+3d migrations), and D (Step 2's placeholder +derivation) are each their own future spec/plan cycle, not in scope here. + +## Problem + +Step 1 today gathers ~9 raw facts in one bash call (already scripted), +then leaves the model to mentally evaluate a 4-state classification plus +three migration triggers with an explicit sequencing rule ("if the primer +is *also* unsplit, run Step 3 to completion first, then Step 3b"). This +nested nested-conditional is exactly the class of logic Phase 4 and Phase +5 already found models get wrong silently when done by hand per +invocation, and this phase's own issue names it as the program's highest +blast radius (some of the triggered steps run `git mv`/`git rm`). + +## Architecture + +``` +primer-detect.sh (I/O) primer-detect.jq (pure decision) + - file-existence checks --> - extract primer's recorded + - git remote get-url git-log block from content, + - git log --oneline -5 diff against actual git log + - git diff --cached --name-only - classify staged files against + - primer file content (if any) the allowlist + - detect inline-outstanding heading + - detect github.com in origin + - run the 4-state + 3-trigger + sequencing tree + - emit KEY=value facts + STEPS= +``` + +`primer-detect.sh` never makes a dispatch decision itself — it is a thin +I/O shim, identical in spirit to `token-overlap.sh`/`candidate-extract.sh`. +All decision logic lives in the `.jq` filter, which takes no I/O and is +therefore fixture-testable with synthetic JSON. + +## Output contract + +`primer-detect.sh <project-dir>` prints, always to stdout on success: + +``` +PRIMER_EXISTS=0|1 +LEARNINGS_EXISTS=0|1 +PROJECT_CONTEXT_EXISTS=0|1 +OUTSTANDING_ITEMS_EXISTS=0|1 +PRIMER_HAS_INLINE_OUTSTANDING=0|1 +BACKLOG_EXISTS=0|1 +ROADMAP_EXISTS=0|1 +GITHUB_ORIGIN=0|1 +LOG_DRIFT=0|1 +CODE_STAGED=0|1 +STEPS=<comma-separated ordered list, possibly empty> +``` + +`STEPS` values, in the only orders the state machine can produce them: +`split`, `outstanding_split`, `backlog_rename`, `backlog_to_issues`, +`refresh`, `init`. Empty `STEPS` means check mode (Step 5) — primer is +current and no migration triggers fired. + +**State machine** (ports the existing prose exactly, no behavior change): + +All facts (`PRIMER_EXISTS` through `CODE_STAGED`) are always computed and +emitted regardless of which branch below fires — no fact is conditionally +skipped, so the full `KEY=value` contract holds even for `STEPS=init`. + +`PRIMER_EXISTS=0` → `STEPS=init`, unconditionally — nothing else to +migrate or refresh yet. Otherwise, evaluate migration triggers in +dependency order, **threading each trigger's effect forward** into the +fact the next trigger reads — not by re-deriving increasingly complex +disjunctions per trigger, which doesn't compose past one link (see the +"Why threading, not disjunctions" note below): + +``` +DO_SPLIT = (PROJECT_CONTEXT_EXISTS == 0) +DO_OSPLIT = (PRIMER_HAS_INLINE_OUTSTANDING == 1) AND (OUTSTANDING_ITEMS_EXISTS == 0) +PROJ_OI = DO_OSPLIT ? 1 : OUTSTANDING_ITEMS_EXISTS +DO_BRENAME = (PROJ_OI == 1) AND (BACKLOG_EXISTS == 0) +PROJ_BL = DO_BRENAME ? 1 : BACKLOG_EXISTS +DO_B2I = (PROJ_BL == 1) AND (GITHUB_ORIGIN == 1) +DO_REFRESH = (LOG_DRIFT == 1) OR (CODE_STAGED == 1) + +STEPS = [split if DO_SPLIT] + [outstanding_split if DO_OSPLIT] + + [backlog_rename if DO_BRENAME] + [backlog_to_issues if DO_B2I] + + [refresh if DO_REFRESH] +``` + +`DO_REFRESH` reads the *raw* `LOG_DRIFT`/`CODE_STAGED` facts, not +projected ones — splitting and renaming don't touch the git-log block or +the staged-file set, so no threading is needed on this last link. + +**Why threading, not disjunctions.** An earlier draft of this spec wrote +`backlog_to_issues`'s condition as `BACKLOG_EXISTS=1 OR (OUTSTANDING_ITEMS_EXISTS=1 +AND BACKLOG_EXISTS=0)` — true now, or about to become true because +`backlog_rename` is queued. That was a real bug fix (caught by +caveman-review) but an incomplete one: `backlog_rename`'s *own* condition +(`OUTSTANDING_ITEMS_EXISTS=1 AND BACKLOG_EXISTS=0`) has the identical +problem one link further up the chain — `outstanding_split`, if also +queued, is what's about to make `OUTSTANDING_ITEMS_EXISTS` true, so a +bare `OUTSTANDING_ITEMS_EXISTS=1` snapshot check silently drops +`backlog_rename` whenever it's chained after `outstanding_split`. +Writing out the "OR about to become true" disjunction a second time +would have worked but doesn't generalize — a fifth chained trigger would +need a three-way disjunction, a sixth a four-way one. Threading a single +projected fact (`PROJ_OI`, `PROJ_BL`) forward through the pipeline scales +to any chain length and is easy to verify by construction: each trigger's +condition reads exactly the fact-state that will actually exist at its +own execution time, given everything queued before it. Verified against +all eleven fixtures below directly in `jq` before this spec was +finalized — see the Testing section. + +## Error handling + +Operational failure (jq missing, `primer-detect.jq` missing or from a +different `CONTRACT_VERSION`, a required git command failing outright) +prints one diagnostic line to stderr and **exits nonzero with no `STEPS=` +line on stdout at all** — no conservative default dispatch. Unlike +`token-overlap.sh` (where empty output safely degrades to "zero matches"), +there is no safe default here: some `STEPS` values gate destructive +migrations, and guessing wrong is worse than stopping. `commands/primer.md` +must treat a missing `STEPS=` line as a hard stop: surface the stderr +diagnostic, do not execute any step. + +## Testing + +Fixture-driven jq tests against synthetic JSON facts (no real git +required), mirroring `meta/superpowers/validation/2026-09-08-token-overlap.md`'s +format. The eleven state-machine cases below (plus a docs-allowlist +variant of case 5, and four operational-failure cases instead of the +single combined item 12 describes conceptually) make up the shipped +smoke test's 16 assertions total — see +`meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh`. + +1. Fresh install (all existence flags 0) → `STEPS=init`. +2. Existing unsplit primer, otherwise current → `STEPS=split`. +3. Split + current + clean → `STEPS=` (empty). +4. Split + current, but recorded log block differs from actual → `STEPS=refresh`. +5. Split + current, non-allowlisted file staged → `STEPS=refresh`. +6. Inline outstanding heading present, no `OUTSTANDING_ITEMS.md` → `STEPS=outstanding_split`. +7. Both unsplit AND inline-outstanding → `STEPS=split,outstanding_split` (order proves the sequencing rule). +8. `OUTSTANDING_ITEMS.md` exists, no `BACKLOG.md` → `STEPS=backlog_rename`. +9. `BACKLOG.md` exists, github origin → `STEPS=backlog_to_issues`. +10. `BACKLOG.md` exists, non-github origin → `STEPS=` (empty) — proves the fossil-file case never fires the GitHub migration. +11. Full worst-case stack (unsplit + inline-outstanding + no outstanding-items file + no backlog file + github origin) → `STEPS=split,outstanding_split,backlog_rename,backlog_to_issues` in that exact order — neither `OUTSTANDING_ITEMS.md` nor `BACKLOG.md` exists yet; both migrations still fire because they're queued via threading (`PROJ_OI`/`PROJ_BL`), which is the whole point of this case. +12. Missing/wrong-version filter, or jq absent → nonzero exit, no `STEPS=` line. + +## Rollout + +`commands/primer.md` Step 1's "Interpret the output" prose (currently +~15 lines of manual state/trigger reasoning) is replaced with: run +`primer-detect.sh`, then execute each name in `STEPS` in order, falling +through to Step 5 (check mode) when `STEPS` is empty. The per-step +sections (2, 3, 3b, 3c, 3d, 4, 5) are unchanged by this sub-project — +only the dispatch that routes into them is scripted. Version bump + +CHANGELOG entry, following the Phase 4/5 precedent. + +## Out of scope + +Sub-projects B (Step 4 test-count rerun), C (Step 3c/3d migration +mechanics themselves — this spec only scripts *whether* they run, not +*what* they do), D (Step 2 placeholder derivation), and E (Step 3/3b +section-bucketing judgment) are each their own future spec/plan cycle. diff --git a/meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh b/meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh new file mode 100755 index 0000000..9339be4 --- /dev/null +++ b/meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh @@ -0,0 +1,161 @@ +#!/usr/bin/env zsh +# primer-detect.sh/.jq smoke test. Hermetic: one scratch git repo per case, +# built fresh via mk_repo. No mocking needed -- every fact is a real file +# or a real git command against a real (throwaway) repository. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +tool="$lib/primer-detect.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +# mk_repo <dir> <split:0|1> <oi_file:0|1> <bl_file:0|1> <inline:0|1> <origin:gh|other> <staged:none|code|docs> +# Builds a fresh scratch repo with .session-continuity/ populated per the +# flags, commits everything, then writes SESSION_PRIMER.md's log block to +# exactly match the post-commit `git log --oneline -5` (never re-committed +# afterward -- see this plan's Task 1 notes on why that avoids a +# self-referential-hash problem). Callers that want DRIFT instead +# overwrite the block themselves after calling mk_repo. +mk_repo() { + local dir="$1" split=$2 oi=$3 bl=$4 inline=$5 origin=$6 staged=$7 + rm -rf "$dir" + mkdir -p "$dir/.session-continuity" + git -C "$dir" init -q + git -C "$dir" config user.email test@example.com + git -C "$dir" config user.name Test + if [[ "$origin" == "gh" ]]; then + git -C "$dir" remote add origin https://github.com/example/repo.git + else + git -C "$dir" remote add origin https://example.com/example/repo.git + fi + : > "$dir/.session-continuity/LEARNINGS.md" + (( split )) && : > "$dir/.session-continuity/PROJECT_CONTEXT.md" + : > "$dir/.session-continuity/ROADMAP.md" + (( oi )) && : > "$dir/.session-continuity/OUTSTANDING_ITEMS.md" + (( bl )) && : > "$dir/.session-continuity/BACKLOG.md" + local heading="" + (( inline )) && heading=$'## Outstanding items\n1. something\n\n' + print -r -- "${heading}# Primer + +placeholder body, overwritten below with the real log block +" > "$dir/.session-continuity/SESSION_PRIMER.md" + git -C "$dir" add -A + git -C "$dir" commit -qm init + local log + log="$(git -C "$dir" log --oneline -5)" + print -r -- "${heading}# Primer + +**Current \`git log --oneline -5\` (primary branch):** + +\`\`\` +$log +\`\`\` +" > "$dir/.session-continuity/SESSION_PRIMER.md" + case "$staged" in + code) print -r -- x > "$dir/src.js"; git -C "$dir" add src.js ;; + docs) print -r -- x >> "$dir/.session-continuity/LEARNINGS.md"; git -C "$dir" add .session-continuity/LEARNINGS.md ;; + esac +} + +steps_of() { bash "$tool" "$1" | awk -F= '/^STEPS=/{print $2}'; } + +# --- 1: fresh install (no .session-continuity/ at all) -> init ------------- +d="$work/case1"; mkdir -p "$d" +git -C "$d" init -q; git -C "$d" config user.email t@t.com; git -C "$d" config user.name T +: > "$d/README.md"; git -C "$d" add -A; git -C "$d" commit -qm init +git -C "$d" remote add origin https://github.com/example/repo.git +[[ "$(steps_of "$d")" == "init" ]] && ok "1: fresh install -> init" || bad "1: got '$(steps_of "$d")'" + +# --- 2: existing unsplit primer, otherwise current -> split ----------------- +d="$work/case2"; mk_repo "$d" 0 0 1 0 other none +[[ "$(steps_of "$d")" == "split" ]] && ok "2: unsplit only -> split" || bad "2: got '$(steps_of "$d")'" + +# --- 3: split + current + clean -> empty ------------------------------------ +d="$work/case3"; mk_repo "$d" 1 0 1 0 other none +[[ "$(steps_of "$d")" == "" ]] && ok "3: split+current+clean -> empty" || bad "3: got '$(steps_of "$d")'" + +# --- 4: recorded log block differs from actual -> refresh ------------------- +d="$work/case4"; mk_repo "$d" 1 0 1 0 other none +print -r -- "# Primer + +**Current \`git log --oneline -5\` (primary branch):** + +\`\`\` +0000000 stale placeholder +\`\`\` +" > "$d/.session-continuity/SESSION_PRIMER.md" +[[ "$(steps_of "$d")" == "refresh" ]] && ok "4: log drift -> refresh" || bad "4: got '$(steps_of "$d")'" + +# --- 5: non-allowlisted file staged -> refresh ------------------------------- +d="$work/case5"; mk_repo "$d" 1 0 1 0 other code +[[ "$(steps_of "$d")" == "refresh" ]] && ok "5: non-allowlisted staged -> refresh" || bad "5: got '$(steps_of "$d")'" + +# --- docs-only staged -> NOT refresh (allowlisted) -------------------------- +d="$work/case5b"; mk_repo "$d" 1 0 1 0 other docs +[[ "$(steps_of "$d")" == "" ]] && ok "5b: docs-only staged -> no refresh (allowlisted)" || bad "5b: got '$(steps_of "$d")'" + +# --- 6: inline heading, no OUTSTANDING_ITEMS.md -> outstanding_split ------- +d="$work/case6"; mk_repo "$d" 1 0 1 1 other none +[[ "$(steps_of "$d")" == "outstanding_split" ]] && ok "6: inline+no file -> outstanding_split" || bad "6: got '$(steps_of "$d")'" + +# --- 7: both unsplit AND inline -> split,outstanding_split (order) --------- +d="$work/case7"; mk_repo "$d" 0 0 1 1 other none +[[ "$(steps_of "$d")" == "split,outstanding_split" ]] && ok "7: unsplit+inline -> split,outstanding_split in order" || bad "7: got '$(steps_of "$d")'" + +# --- 8: OUTSTANDING_ITEMS.md exists, no BACKLOG.md -> backlog_rename ------- +d="$work/case8"; mk_repo "$d" 1 1 0 0 other none +[[ "$(steps_of "$d")" == "backlog_rename" ]] && ok "8: outstanding file, no backlog -> backlog_rename" || bad "8: got '$(steps_of "$d")'" + +# --- 9: BACKLOG.md exists, github origin -> backlog_to_issues -------------- +d="$work/case9"; mk_repo "$d" 1 0 1 0 gh none +[[ "$(steps_of "$d")" == "backlog_to_issues" ]] && ok "9: backlog exists, github -> backlog_to_issues" || bad "9: got '$(steps_of "$d")'" + +# --- 10: BACKLOG.md exists, non-github origin -> empty (fossil, no GH call) - +d="$work/case10"; mk_repo "$d" 1 0 1 0 other none +[[ "$(steps_of "$d")" == "" ]] && ok "10: backlog exists, non-github -> empty (fossil)" || bad "10: got '$(steps_of "$d")'" + +# --- 11: full worst-case stack, exact order --------------------------------- +d="$work/case11"; mk_repo "$d" 0 0 0 1 gh none +[[ "$(steps_of "$d")" == "split,outstanding_split,backlog_rename,backlog_to_issues" ]] \ + && ok "11: full stack fires in dependency order" || bad "11: got '$(steps_of "$d")'" + +# --- 12: operational failure -- missing filter, no STEPS line at all ------- +badlib="$work/badlib"; mkdir -p "$badlib" +cp "$lib/primer-detect.sh" "$badlib/" +out="$(bash "$badlib/primer-detect.sh" "$work/case3" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "12: missing filter -> nonzero exit, no STEPS= line" || bad "12: rc=$rc out='$out'" + +# --- 13: operational failure -- not a git repo ------------------------------ +notgit="$work/notgit"; mkdir -p "$notgit" +out="$(bash "$tool" "$notgit" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "13: not a git repo -> nonzero exit, no STEPS= line" || bad "13: rc=$rc out='$out'" + +# --- 14: operational failure -- wrong CONTRACT_VERSION ----------------------- +wronglib="$work/wronglib"; mkdir -p "$wronglib" +cp "$lib/primer-detect.sh" "$wronglib/" +sed 's/CONTRACT_VERSION=1/CONTRACT_VERSION=99/' "$lib/primer-detect.jq" > "$wronglib/primer-detect.jq" +out="$(bash "$wronglib/primer-detect.sh" "$work/case3" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "14: wrong CONTRACT_VERSION -> nonzero exit, no STEPS= line" || bad "14: rc=$rc out='$out'" + +# --- 15: operational failure -- jq absent from PATH ------------------------- +nojq="$work/nojq"; mkdir -p "$nojq/bin" +for b in bash git awk grep sed head cat mktemp dirname; do + p="$(command -v "$b")"; [[ -n "$p" ]] && ln -sf "$p" "$nojq/bin/$b" +done +out="$(PATH="$nojq/bin" bash "$tool" "$work/case3" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"STEPS="* ]] \ + && ok "15: jq absent from PATH -> nonzero exit, no STEPS= line" || bad "15: rc=$rc out='$out'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) From eee17b8ea93859e903a435e1f88f0c77b5cc1df0 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Wed, 9 Sep 2026 09:55:38 -0700 Subject: [PATCH 14/20] Determinism Phase 6 sub-project B: test-count-rerun.sh/.jq (#57) * docs: catch up primer/LEARNINGS/plan doc for merged PRs #50, #52 Prior sessions merged Phase 4 (checklist assembly, PR #50) and Phase 6 sub-project A (primer-detect, PR #52) but left the primer refresh and the Phase 4 plan doc staged/untracked. Committing the accurate record. * docs: design spec for test-count-rerun.sh/.jq (Phase 6 sub-project B) Scopes Determinism Phase 6 sub-project B: scripting commands/primer.md Step 4 item 3's test-count majority-vote rerun, mirroring the primer-detect.sh/.jq I/O-shim-plus-pure-decision split from sub-project A. Issue #43. * fix(docs): resolve caveman-review findings on test-count-rerun spec Drops the separate run-unparseable MODE value (only ever reached from inside MODE=run's own retry loop, not a real dispatch branch) in favor of a fold-in UNPARSEABLE flag. Generalizes the majority-vote rule to handle unparseable runs explicitly (2-of-2-parseable still pins; a disagreement with one unparseable run is spread, not a false no-drift). Makes DRIFT/SPREAD mutually exclusive by construction. Documents that only the pass count (N) round-trips for drift comparison, never the fail count (M) -- an inherited limitation, not a new one. Extends the fixture list to cover the unparseable-run paths on both layers. * fix(docs): resolve caveman-review findings on test-count-rerun plan Part A's jq_run() helper never passed --arg test_cmd, but the filter references $test_cmd -- jq errors at compile time on an unbound var (it is not null-by-default), so every A1-A10 assertion would have failed with "$test_cmd is not defined" rather than testing what they claim to test. Fixed by always passing --arg test_cmd "" in jq_run. Also swaps two substring-match assertions (B4, B5) for the existing exact-field jq_field helper, since a prefix match on PINNED_COUNT=4 would false-positive against PINNED_COUNT=45. * feat: add test-count-rerun.sh/.jq, scripting primer Step 4's rerun vote * refactor: primer.md Step 4 item 3 dispatches via test-count-rerun.sh * docs: Phase 6 sub-project B doc pointers, changelog, and version bump --- .claude-plugin/plugin.json | 2 +- .session-continuity/LEARNINGS.md | 30 + .session-continuity/SESSION_PRIMER.md | 30 +- CHANGELOG.md | 5 + commands/primer.md | 52 +- hooks/lib/test-count-rerun.jq | 34 + hooks/lib/test-count-rerun.sh | 146 +++ ...-determinism-phase-4-checklist-assembly.md | 1006 +++++++++++++++++ .../plans/2026-09-09-test-count-rerun.md | 695 ++++++++++++ .../2026-09-02-determinism-program-design.md | 22 +- .../2026-09-09-test-count-rerun-design.md | 198 ++++ .../2026-09-09-test-count-rerun-smoke.zsh | 235 ++++ 12 files changed, 2429 insertions(+), 26 deletions(-) create mode 100644 hooks/lib/test-count-rerun.jq create mode 100755 hooks/lib/test-count-rerun.sh create mode 100644 meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md create mode 100644 meta/superpowers/plans/2026-09-09-test-count-rerun.md create mode 100644 meta/superpowers/specs/2026-09-09-test-count-rerun-design.md create mode 100755 meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 1654d50..54eebd1 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session-continuity", - "version": "0.32.0", + "version": "0.33.0", "description": "Cross-session memory for Claude Code projects via four in-repo docs: SESSION_PRIMER.md (current state), PROJECT_CONTEXT.md (stable repo context), ROADMAP.md (strategic direction), and LEARNINGS.md (hard-won bugs), plus GitHub Issues labeled backlog for the work queue.", "author": { "name": "Tal Golan" diff --git a/.session-continuity/LEARNINGS.md b/.session-continuity/LEARNINGS.md index 8b47f6c..93519a1 100644 --- a/.session-continuity/LEARNINGS.md +++ b/.session-continuity/LEARNINGS.md @@ -16,6 +16,7 @@ within each group. each time it appends a new entry. --> +- A capture regex spanning a multi-line git-log fenced block matched fine via… — #19 - A subagent reported commit `9b2f504` in repo A; `git rev-parse --verify` in… — #18 - After GitHub squash-merged PR #20, `git merge --ff-only — #15 - Clean-machine acceptance test for v0.4.0. `/session-continuity:primer` ran init mode cleanly, asked for… — #4 @@ -24,6 +25,7 @@ within each group. - Discovered while hardening the Step 2 transcript-extraction jq filter after a user… — #10 - Documented as an accepted tradeoff while designing the commit-time gates (`meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md`'s Tradeoffs… — #14 - Every run of that one check silently wrote a real entry into… — #12 +- Implementing the same state machine directly in jq (to write real tests,… — #20 - In a live Claude session, the hook runs (verified via debug logs)… — #1 - Real invocation of `/session-continuity:primer` after installing the change failed every one of… — #11 - The Bash call is refused outright: "This session is isolated in the… — #8 @@ -124,6 +126,34 @@ The original awk range fails because the same pattern matches both the start and ## Slash command skill authoring +### 20. A per-link "OR about to become true" disjunction fix for one chained trigger doesn't generalize to the next link +Slug: chained-trigger-threading-not-disjunction +Trigger: Write /\.jq$/ + +**The trap.** Fixing a state-machine trigger's stale-fact bug by adding "OR about to become true because the prior step is queued" feels like a complete fix — it matches the exact bug reported and verifies correct for that one link. + +**Symptom.** Implementing the same state machine directly in jq (to write real tests, not just re-derive it by hand) surfaced an identical bug one link further up the dependency chain: the trigger feeding the just-fixed one had the exact same stale-snapshot problem, because the whole `STEPS` list is computed from one upfront fact snapshot before any step actually runs — a queued-but-not-yet-run migration can't have changed the fact the next trigger reads. + +**Fix.** Replace per-link disjunctions with threading a single projected fact forward through the pipeline (`PROJ_X = triggered ? 1 : raw_fact`), so each trigger reads the fact-state that will actually exist at its own execution time given everything queued before it. This generalizes to any chain length; a disjunction has to be rewritten wider for every additional link. + +**Diagnostic signal** *(optional)*. A chained dependent-trigger state machine — trigger B's precondition depends on a fact trigger A is about to change — where only the last-reported link got an "about to become true" fix: check every earlier link in the chain for the identical bug, not just the one the report named. + +--- + +### 19. jq/Oniguruma's "m" flag means dot-matches-newline, not PCRE's "s" +Slug: jq-oniguruma-dotall-flag-swap +Trigger: Write /\.jq$/ + +**The trap.** jq's regex flags look like they follow PCRE convention, where "s" (dotall) makes `.` match newlines — a reasonable assumption since dotall-as-"s" is the common cross-language default and jq's own docs describe the flags tersely. + +**Symptom.** A capture regex spanning a multi-line git-log fenced block matched fine via `test()` right up through the literal fence delimiter, then silently returned zero matches — not an error, an empty stream — once a `.*?` needed to cross the block's internal newlines, using flag `"s"`. + +**Fix.** jq/Oniguruma's `"m"` flag is what makes `.` match newlines; `"s"` instead restricts `^`/`$` to string start/end (single-line anchor mode) — the letters are swapped from PCRE. Use `"m"` whenever a jq regex's `.` must cross line breaks. + +**Diagnostic signal** *(optional)*. A jq `capture()`/`match()` against known-good multi-line text returns nothing — not an error, an empty stream — check the flag letter before suspecting the pattern itself. + +--- + ### 10. jq's `split("\n")[0]` returns `null` on an empty string — crashes the next `gsub` in a chain Slug: jq-split-empty-string-null Trigger: * /split\("\n"\)\[0\]/ diff --git a/.session-continuity/SESSION_PRIMER.md b/.session-continuity/SESSION_PRIMER.md index ba60047..61e7ad8 100644 --- a/.session-continuity/SESSION_PRIMER.md +++ b/.session-continuity/SESSION_PRIMER.md @@ -20,6 +20,32 @@ rarely. ## Current state +- **Determinism Phase 6 sub-project A shipped (issue #43 partially — + 4 of 5 sub-projects remain, PR #52, merged).** `commands/primer.md` + Step 1's hand-evaluated 4-state-plus-3-migration-trigger dispatch + (~15 lines of nested-conditional prose with an easy-to-miss sequencing + rule) replaced by `hooks/lib/primer-detect.sh`/`.jq`, which threads + each trigger's effect forward into the fact the next trigger reads + (`outstanding_split`→`backlog_rename`→`backlog_to_issues`) rather than + writing per-trigger "OR about to become true" disjunctions — that + approach was tried during implementation-first verification, found not + to compose past one chained link (a real bug caught twice: once by + caveman-review, once by re-deriving the logic directly in jq), and + replaced. Executed via subagent-driven-development (3 tasks, each + task-reviewed) plus a final whole-branch review (Opus) that found one + more real gap before merge: the terminal-step rule only ran Step 5 + when `STEPS` was fully empty, silently skipping the status report for + a migration-only `STEPS` list — fixed, re-reviewed clean. 16/16 smoke + assertions (real scratch git repos). Design spec: + `meta/superpowers/specs/2026-09-08-primer-detect-design.md`. Plan: + `meta/superpowers/plans/2026-09-08-primer-detect.md`. Sub-projects + B (Step 4's test-count majority-vote rerun), C (Step 3c/3d's `git + mv`/`git rm` mechanics), D (Step 2's placeholder derivation), and E + (Step 3/3b's section-bucketing judgment) remain pending on issue #43. + One parked minor: the corrected terminal-step rule also fires Step 5 + after `STEPS=init` on every fresh install (Step 2 already prints its + own terminal report) — harmless, one extra status paragraph, happens + once per repo ever. v0.32.0. - **Determinism Phase 5 re-scoped and shipped (issue #42, branch `determinism-phase-5-token-overlap`).** Original scoping conflated two unrelated things: `candidate-extract.jq`'s `overlap()` (a Jaccard ratio @@ -672,11 +698,11 @@ rarely. **Current `git log --oneline -5` (primary branch):** ``` -66468ee refactor: end-session's overlap gate is now hooks/lib/token-overlap.sh/.jq +de381a8 feat: primer-detect.sh/.jq, scripting /session-continuity:primer's Step 1 dispatch (Phase 6 sub-project A) (#52) +8dfd9c9 refactor: end-session's overlap gate is now hooks/lib/token-overlap.sh/.jq (#51) ddaccca Merge pull request #50 from talgolan/determinism-phase-4-step3-checklist 40f5496 fix(docs): inline sign-off strings in end-session fallback path b7b82f3 docs: Phase 4 doc pointers, changelog, and version bump for the checklist script -17d866d refactor: end-session Step 4 becomes a pure timing step, sign-off now owned by checklist-assemble.sh ``` Regenerate this block whenever you commit — see diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cca560..7a11a86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.33.0] — 2026-09-09 + +### Changed +- **`/session-continuity:primer`'s Step 4 test-count rerun is now scripted.** New `hooks/lib/test-count-rerun.sh`/`.jq` replace ~8 lines of hand-evaluated majority-vote prose (skip-check, run-once-then-compare, retry-to-3-on-mismatch, pin-to-majority, spread-on-3-way-disagreement) with one script call. The `.jq` filter's vote algorithm is mode-agnostic — the `skip`/`no-command`/`no-count` cases' "always empty" outputs fall out of the same generic majority computation applied to a 0- or 1-element observation array, with no per-mode special casing. Unparseable test runs (timeout, crash, no recognizable count) are now handled explicitly: they consume a retry slot but cast no vote, so a 2-of-2 parseable majority still pins even when the third run was unparseable, and a genuine 2-way disagreement with one unparseable run reports spread rather than a false no-drift. Determinism Phase 6 (#43) sub-project B; sub-projects C-E remain pending. + ## [0.32.0] — 2026-09-08 ### Changed diff --git a/commands/primer.md b/commands/primer.md index f0ac916..5ac4573 100644 --- a/commands/primer.md +++ b/commands/primer.md @@ -282,22 +282,48 @@ the file unless the issues exist. ``` Use the output above to regenerate the primer's block. -3. If the primer has a test-counts section, decide whether to re-run it. - Do this as **one Bash call**, timed, tracking a `RETRIES` count (0 - if skipped or the first run matched, else the number of *extra* - runs actually executed beyond the first): - - **Skip the rerun** if `git diff <last-primer-commit>..HEAD --name-only` (the commit range since the primer was last touched) contains no file outside `.session-continuity/` — no source or test file changed, so the recorded count cannot have drifted. Reuse this diff if already computed elsewhere in this flow; don't recompute it just for this check. - - **Otherwise, run the test command(s) once.** If that single run's count matches the primer's recorded count, stop there — no drift on this axis, no further runs. - - **Only if that first run disagrees with the recorded count**, retry up to 2 more times (3 runs total) to rule out flakiness before reporting drift — a single sample can swing a pass/fail count and produce a false drift alarm. Pin to the count seen in ≥2 of the 3 runs. If that pinned count matches the primer's recorded count, the first run was the flake — no drift. If it differs, report drift with the pinned count. If all three runs disagree with each other, surface the spread (`saw 1162 / 1161 / 1162 across 3 runs — using 1162; suite is unstable`) instead of silently picking one. +3. Run the shared test-count rerun script, timed: - This keeps the common cases cheap: zero test runs when no relevant file changed, one run when relevant files changed but the count still holds, and the full 3-run majority vote only when there's an actual discrepancy to resolve. - - At the end of this Bash call (whichever branch above ran), call: ```bash - bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-test-count-rerun --duration="$_PERF_DURATION" --retries="$RETRIES" + _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) + source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" 1; then + RERUN_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" . "$LAST_PRIMER_COMMIT" 2>&1)" + RERUN_STATUS=$? + else + RERUN_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + RERUN_STATUS=1 + fi + _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") + RETRIES=$(printf '%s' "$RERUN_OUTPUT" | awk -F= '/^RETRIES=/{print $2}') + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-test-count-rerun --duration="$_PERF_DURATION" --retries="${RETRIES:-0}" + echo "$RERUN_OUTPUT" + echo "RERUN_STATUS=$RERUN_STATUS" ``` - using the same `_PERF_START`/`_PERF_END`/`_PERF_DURATION` pattern - shown in item 2 above, captured around this whole check. + + **If `RERUN_STATUS` is nonzero, or `$RERUN_OUTPUT` has no `MODE=` line:** + report `$RERUN_OUTPUT` to the user and fall back to `TBD` for this + axis — never fabricate a drift verdict from a failed script. + + **Otherwise**, report per `MODE`: + - `skip` — no relevant file changed; say nothing (matches today's + silent skip). + - `no-command` — no test command recorded; nothing to check. + - `no-count`, `RETRIES=0`, `DRIFT=0` always — nothing recorded yet + to compare against; no report needed on this axis. + - `run` with `DRIFT=0` — the count held (whether on the first try or + after majority-vote confirmation); no report needed. + - `run` with `DRIFT=1` — report drift using `PINNED_COUNT` + (`"Test count drifted: recorded <RECORDED_COUNT>, now + <PINNED_COUNT> (confirmed over <RETRIES>+1 runs)."`). + - `run` with `SPREAD=1` — report instability using the comma-joined + `OBSERVED` values (`"Test suite is unstable: saw + <OBSERVED, /-joined> across 3 runs."`), not a drift verdict. + - `run` with `UNPARSEABLE=1` and no `PINNED_COUNT` — report + `"Test command produced no parseable count after <RETRIES>+1 + attempts."` 4. **Surface activity since the last primer refresh.** **One Bash call**, timed: diff --git a/hooks/lib/test-count-rerun.jq b/hooks/lib/test-count-rerun.jq new file mode 100644 index 0000000..fbed89c --- /dev/null +++ b/hooks/lib/test-count-rerun.jq @@ -0,0 +1,34 @@ +# CONTRACT_VERSION=1 +# hooks/lib/test-count-rerun.jq — pure vote/drift/spread decision for +# /session-continuity:primer Step 4's test-count rerun. Invoked via +# test-count-rerun.sh; see that file for the CLI contract and +# meta/superpowers/specs/2026-09-09-test-count-rerun-design.md for the +# full output contract this implements. +# +# Mode-agnostic by design: $mode is pass-through only (it never gates a +# branch here). skip/no-command/no-count's "always empty" outputs fall +# out of running this same algorithm against a 0- or 1-element $observed +# array — see the design spec's "MODE=run" outcomes table for why a +# majority can never be pinned from fewer than 2 parseable votes. + +($observed | length) as $n +| ($observed | map(select(. != null))) as $parseable +| (if $n == 0 then 0 else $n - 1 end) as $retries +| (any($observed[]; . == null)) as $unparseable +| ($parseable | group_by(.) | map({value: .[0], count: length}) + | map(select(.count >= 2))) as $majority +| ($majority[0].value // null) as $pinned +| (if $pinned != null then false + else ($parseable | unique | length) >= 2 + end) as $spread +| ($pinned != null and $recorded != null and $pinned != $recorded) as $drift + +| "TEST_CMD=" + ($test_cmd // ""), + "RECORDED_COUNT=" + (if $recorded == null then "" else ($recorded|tostring) end), + "MODE=" + $mode, + "RETRIES=" + ($retries|tostring), + "OBSERVED=" + ($observed | map(if . == null then "" else (.|tostring) end) | join(",")), + "UNPARSEABLE=" + (if $unparseable then "1" else "0" end), + "DRIFT=" + (if $drift then "1" else "0" end), + "PINNED_COUNT=" + (if $pinned == null then "" else ($pinned|tostring) end), + "SPREAD=" + (if $spread then "1" else "0" end) diff --git a/hooks/lib/test-count-rerun.sh b/hooks/lib/test-count-rerun.sh new file mode 100755 index 0000000..605048d --- /dev/null +++ b/hooks/lib/test-count-rerun.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/test-count-rerun.sh — test-count majority-vote rerun for +# /session-continuity:primer Step 4 (Refresh mode). See +# meta/superpowers/specs/2026-09-09-test-count-rerun-design.md for the +# full contract this implements (unchanged behavior from the prior +# hand-evaluated prose, just executable instead of hand-derived per +# invocation) and meta/superpowers/plans/2026-09-09-test-count-rerun.md +# for the implementation plan. +# +# Usage: test-count-rerun.sh <project-dir> <last-primer-commit> +# Prints KEY=value lines to stdout on success: TEST_CMD, RECORDED_COUNT, +# MODE (skip|no-command|no-count|run), RETRIES, OBSERVED, UNPARSEABLE, +# DRIFT, PINNED_COUNT, SPREAD. +# +# Operational failure (jq missing, test-count-rerun.jq missing or from a +# different CONTRACT_VERSION, <project-dir> not inside a git repository, +# PROJECT_CONTEXT.md unreadable) prints one diagnostic line to stderr and +# exits 1 with NO MODE= line on stdout at all. + +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JQ_FILTER="$SCRIPT_DIR/test-count-rerun.jq" +DIR="${1:-.}" +LAST_PRIMER_COMMIT="${2:-}" + +die() { # <message> + printf 'test-count-rerun.sh: %s\n' "$1" >&2 + exit 1 +} + +[[ -n "$LAST_PRIMER_COMMIT" ]] \ + || die "usage: test-count-rerun.sh <project-dir> <last-primer-commit>" +command -v jq >/dev/null 2>&1 \ + || die "jq is not installed, so the test-count rerun cannot be computed." +[[ -r "$JQ_FILTER" ]] \ + || die "test-count-rerun.jq is missing from $SCRIPT_DIR — the plugin cache is incomplete. Run \`/session-continuity:update\`." +grep -q '^# CONTRACT_VERSION=1$' "$JQ_FILTER" \ + || die "test-count-rerun.jq is from a different plugin version — run \`/session-continuity:update\`." +git -C "$DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1 \ + || die "$DIR is not inside a git repository." +CONTEXT_FILE="$DIR/.session-continuity/PROJECT_CONTEXT.md" +[[ -r "$CONTEXT_FILE" ]] \ + || die "$CONTEXT_FILE is not readable." + +# --- extract the Test-expectations summary line ---------------------------- +# Skip any HTML-comment lines (single- or multi-line <!-- ... -->) so a +# template's own exemplar comment is never mistaken for real content. +SUMMARY_LINE="$(awk ' + /^## Test expectations/ { insec=1; next } + insec && /^## / { exit } + insec { + if ($0 ~ /<!--/) incomment=1 + if (!incomment && $0 !~ /^[[:space:]]*$/) { print; exit } + if ($0 ~ /-->/) incomment=0 + } +' "$CONTEXT_FILE")" + +TEST_CMD="" +if [[ "$SUMMARY_LINE" =~ ^\`([^\`]+)\` ]]; then + TEST_CMD="${BASH_REMATCH[1]}" +fi + +RECORDED_COUNT="" +if [[ -n "$TEST_CMD" ]]; then + RECORDED_COUNT="$(printf '%s' "$SUMMARY_LINE" | grep -oE '[0-9]+ pass(ed)?' | head -1 | grep -oE '^[0-9]+' || true)" +fi + +# --- mode dispatch (labeling only -- the .jq filter's vote logic is the +# same regardless of which label sh assigns here) ---------------------- +if [[ -z "$TEST_CMD" ]]; then + MODE="no-command" +else + CHANGED_FILES="$(git -C "$DIR" diff "$LAST_PRIMER_COMMIT"..HEAD --name-only 2>/dev/null || true)" + SKIP=1 + while IFS= read -r f; do + [[ -z "$f" ]] && continue + case "$f" in .session-continuity/*) ;; *) SKIP=0 ;; esac + done <<<"$CHANGED_FILES" + if [[ "$SKIP" -eq 1 ]]; then + MODE="skip" + elif [[ -z "$RECORDED_COUNT" ]]; then + MODE="no-count" + else + MODE="run" + fi +fi + +# --- run the command 0-3 times per mode ------------------------------------- +# run_once's exit code is deliberately never inspected: "unparseable" is +# defined purely by the absence of a recognizable count in the output, +# not by a nonzero exit or a timeout. A `timeout`-killed run and a +# zero-exit run that simply printed no count both fall through to the +# same "no parseable count" outcome below -- there is exactly one code +# path for both, which is why the smoke test (B6) only needs to exercise +# unparseable *output*, not a separate timeout-specific fixture. +run_once() { # prints the parsed count, or nothing, on stdout + local out + out="$(cd "$DIR" && timeout 120 bash -c "$TEST_CMD" 2>&1)" + printf '%s' "$out" | grep -oE '[0-9]+ pass(ed)?' | head -1 | grep -oE '^[0-9]+' || true +} + +OBSERVED_JSON="[]" +case "$MODE" in + skip|no-command) + : # OBSERVED stays empty; the command never runs. + ;; + no-count) + v="$(run_once)" + OBSERVED_JSON="[$( [[ -n "$v" ]] && echo "$v" || echo null )]" + ;; + run) + v1="$(run_once)" + if [[ -n "$v1" && "$v1" == "$RECORDED_COUNT" ]]; then + OBSERVED_JSON="[$v1]" + else + v2="$(run_once)" + v3="$(run_once)" + to_json() { [[ -n "$1" ]] && echo "$1" || echo null; } + OBSERVED_JSON="[$(to_json "$v1"),$(to_json "$v2"),$(to_json "$v3")]" + fi + ;; +esac + +RECORDED_JSON="null" +[[ -n "$RECORDED_COUNT" ]] && RECORDED_JSON="$RECORDED_COUNT" + +ERRFILE="$(mktemp)" +RESULT="$( + jq -r -n \ + --arg test_cmd "$TEST_CMD" \ + --arg mode "$MODE" \ + --argjson recorded "$RECORDED_JSON" \ + --argjson observed "$OBSERVED_JSON" \ + -f "$JQ_FILTER" 2>"$ERRFILE" +)" +JQ_STATUS=$? +DETAIL="$(head -1 "$ERRFILE" 2>/dev/null)" +rm -f "$ERRFILE" + +if [[ "$JQ_STATUS" -ne 0 || -z "$RESULT" ]]; then + die "the vote filter failed: ${DETAIL:-jq exited $JQ_STATUS}" +fi + +printf '%s\n' "$RESULT" diff --git a/meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md b/meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md new file mode 100644 index 0000000..67f0cab --- /dev/null +++ b/meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md @@ -0,0 +1,1006 @@ +# Determinism Phase 4 — `end-session` Step 3 checklist assembly — Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace `commands/end-session.md` Step 3's model-assembled checklist (six git commands, hand-formatted rows, a hand-composed suggested-commit message, and a hand-picked sign-off line) with one script, `hooks/lib/checklist-assemble.sh`, that consumes the six git outputs plus a `tag<TAB>verdict<TAB>citation` backlog-verdict file and prints the finished eight-row checklist, the backlog tallies, every row's ✓/⚠️ marker, and the terminal sign-off line, verbatim. + +**Architecture:** `checklist-assemble.sh` follows the same shape as `hooks/lib/candidate-render.sh` (Phase 2): one JSON object on stdin carrying every git-derived and model-decided value, one optional positional arg for the backlog-verdict TSV path, one text blob on stdout, always exit 0, one `SC-FALLBACK:` escape hatch for malformed input. Step 3's Bash block builds that JSON in the same round trip that runs the six (now seven — see Task 3) git commands, pipes it through the script, and prints the result unchanged. Because the script's own output now includes the terminal sign-off line, Step 4 no longer prints any checklist-derived text of its own — it becomes a pure timing/logging step. + +**Tech Stack:** Bash, `jq` (already a hard dependency via `candidate-render.sh`), zsh (smoke tests only). + +**Spec:** `meta/superpowers/specs/2026-09-02-determinism-program-design.md` (Phase 4 entry). That entry's line-number citations (612-675, 759-773, 687-701) are stale — they were written against a pre-Phase-5 `end-session.md` (45,284 bytes); the current file is 587 lines. This plan cites current line numbers throughout and Task 6 updates the spec's pointer. + +## Global Constraints + +- Every new script prints best-effort output and **always exits 0** — `checklist-assemble.sh` sits inside `end-session`'s close-out ritual, which must never abort on a formatting failure (same rule `candidate-render.sh` and `perf-log.sh` already follow). +- `checklist-assemble.sh` carries a `# CONTRACT_VERSION=1` header and is called through `require_script` from `commands/end-session.md`, exactly like `candidate-extract.sh` and `resolve-transcript.sh` already are. +- **Never invent a value.** Every field the script cannot resolve is either omitted (per the existing per-row omission rules already in `end-session.md`) or degrades to the script's own fixed fallback text — never a paraphrase, never a placeholder. +- **One round trip per Bash call**, unchanged from the existing convention: Step 3's "gather facts" call stays one call: seven git commands, the JSON assembly, and the `checklist-assemble.sh` invocation, timed exactly as today. +- **Backlog verdicts never mutate the primer.** Unchanged from today — the TSV file this plan introduces is a read-only report of verdicts already decided in Step 1; nothing about closing an item changes. +- Do not touch `overlap()`/`candidate-extract.jq` (backlog item #40) or Phase 6's `primer` detect/migrate/init/drift logic (#43) — out of scope. +- Do not touch `primer-status.sh` — it already reads `BACKLOG_COUNT` via `backlog-issues.sh --count` (shipped in v0.29.0), so it needs no change for this plan. + +--- + +## File Structure + +| File | Responsibility | +|---|---| +| `hooks/lib/checklist-assemble.sh` (new) | Reads one JSON object from stdin plus an optional backlog-TSV path argument; prints the finished eight-row checklist, suggested-commit block, and terminal sign-off line as one text blob. | +| `hooks/lib/perf-log.sh` (modified) | `write_record`'s gitignore-ensure list gains the new scratch TSV path, so it's never accidentally tracked if a ritual is interrupted before Step 3's cleanup runs. | +| `commands/end-session.md` (modified) | Fast path gains one cheap backlog-count call. Backlog verification gains a TSV-writing step. Step 3's "Gather the facts" / "Emit the checklist" / "Suggested commit message" / "Example output" sections collapse to one script call plus its `SC-FALLBACK:` branch. Step 4 drops all of its own printed text, keeping only the timing calls. | +| `meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh` (new) | Smoke test for the new script — every row, every branch, the fallback path. | +| `meta/superpowers/specs/2026-09-02-determinism-program-design.md` (modified) | Phase 4 entry collapses to a pointer at this plan, per the doc's own "Entry format" rule. | +| `CHANGELOG.md` (modified) | New version entry. | + +--- + +### Task 1: `hooks/lib/checklist-assemble.sh` + +**Files:** +- Create: `hooks/lib/checklist-assemble.sh` +- Test: `meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh` + +**Interfaces:** +- Produces: `bash checklist-assemble.sh [<backlog-tsv-path>]`, reading one JSON object from stdin. Prints the finished checklist text (eight rows, blank line, sign-off line) on stdout. Always exits 0. +- Consumes: `jq` (hard dependency, same as `candidate-render.sh`). If `<backlog-tsv-path>` is given and `backlog_mode=="normal"` in the input JSON, reads that file as `tag\tverdict\tcitation` lines (one open backlog item per line). + +**JSON input contract** (every key optional except `staged`/`unstaged`/`untracked`/`branch`/`primer`/`learnings`/`backlog_mode`, which must always be present — `checklist-assemble.sh` treats a missing required key the same as malformed JSON, i.e. the `SC-FALLBACK:` branch): + +```json +{ + "staged": ["path/a", "path/b"], + "unstaged": ["path/c"], + "untracked": ["path/d"], + "branch": "main", + "detached": false, + "short_sha": "abc1234", + "upstream": "origin/main", + "ahead": 0, + "primer": "refreshed", + "learnings": [{"number": 7, "title": "awk range collapse on single-version CHANGELOG"}], + "backlog_mode": "normal", + "backlog_fastpath_count": null, + "commit_subject": null +} +``` + +- `detached`: `true` means `branch` is the literal `"HEAD"` from `git rev-parse --abbrev-ref HEAD`; `upstream`/`ahead` are ignored when `true`. +- `upstream`: `null` (not the literal string `"null"` — real JSON null) when `git rev-parse --abbrev-ref @{u}` failed. `ahead` is `null` under the same condition. +- `primer`: one of `"refreshed"`, `"closed"`, `"current"`. +- `learnings`: empty array when Step 2 captured nothing. +- `backlog_mode`: one of `"normal"`, `"none"`, `"unavailable"`, `"not-migrated"`, `"fast-path"`. `"fast-path"` requires `backlog_fastpath_count` (an integer). `"normal"` requires the positional TSV path argument to be non-empty and readable — an empty/unreadable path when `backlog_mode=="normal"` is treated as zero backlog items (not a fallback — an empty TSV is a valid "no open items survived the overlap gate" state, but a *missing* one attached to `"normal"` mode is a caller bug, silently degraded to zero rather than crashing). +- `commit_subject`: `null` unless staged files exist AND at least one staged path is outside `.session-continuity/` — in that mixed/code case, the caller (the model) supplies its own conventional-commit subject line here (this is retained model judgment per the spec's "What stays model work" list, item 5). When staged is all-`.session-continuity/`, this field is ignored entirely — the script uses its own literal subject. + +**Output rows, in order** (blank line, then the sign-off line, are appended after row 8): + +1. **Primer refresh** — `✓ Primer refreshed and staged` / `✓ Primer updated (outstanding item(s) closed)` / `✓ Primer already current (no-op)`, keyed off `primer`. +2. **New learnings** — `✓ No new learnings` if `learnings` is empty; else `✓ N LEARNINGS entry/entries captured (#X, "title", #Y, "title", …)` — singular "entry" for N=1, plural "entries" otherwise, comma-joined `#N, "title"` pairs in array order. +3. **Backlog** — see the mode table below. +4. **Staged files** — `✓ Staged: a, b, c` (comma-joined, array order) or `✓ Nothing staged` if `staged` is empty. +5. **Unstaged modifications** — `✓ No unstaged modifications` if `unstaged` is empty, else `⚠️ Unstaged: a, b, c`. +6. **Untracked files** — `✓ No untracked files` if `untracked` is empty, else `⚠️ N untracked: a, b, c — ignore, add, or delete?` (N is `untracked`'s length). +7. **Unpushed commits** — see the branch-state table below. +8. **Suggested commit** — omitted entirely (no row, no blank line in its place) if `staged` is empty. Otherwise: `→ Suggested:` followed by a fenced ` ```\ngit commit -m "<subject>"\n``` ` block, where `<subject>` is: the literal `docs: update session continuity` if every entry in `staged` starts with `.session-continuity/`; else `commit_subject` if non-null; else the mechanical fallback `chore: update N file(s)` (N = `staged`'s length) if `commit_subject` is null in the mixed/code case — this fallback is deliberately generic (never fabricates a theme) so the ritual never blocks on a missing judgment call, but always losslessly reflects the actual N. + +**Backlog row, by `backlog_mode`:** + +| `backlog_mode` | Marker | Text | +|---|---|---| +| `none` | ✓ | `Backlog: none tracked` | +| `unavailable` | ✓ | `Backlog: GitHub queue unavailable — run /session-continuity:doctor` | +| `not-migrated` | ✓ | `Backlog: not migrated — run /session-continuity:primer` | +| `fast-path` | ✓ | `Backlog: N tracked — not re-verified this session (no repo changes since last close-out)` (N = `backlog_fastpath_count`) | +| `normal` | ✓ if zero `appears-DONE` rows in the TSV, else ⚠️ | `Backlog: N tracked — k appears-DONE (tag, "citation", tag, "citation", …), m still-open (tag, tag, …), j manual (tag, tag, …)` — N = total TSV lines; k/m/j = counts per verdict; the `appears-DONE` clause is the only one carrying citations (still-open and manual list bare tags), and any verdict with zero items **and its parenthetical are omitted from the sentence entirely** (never print `0 still-open ()`, only the fragments for k/m/j that are >0, comma-joined) | + +> **Proven-gate:** N/A — the fast-path row's `not re-verified` text +> above is a quoted UI string this script prints, not a proven/verified +> claim about this plan itself. +> +> **Evidence-gate:** N/A — the `cleanup` mention above is a scratch-TSV +> gitignore entry, not a smoke-test teardown that could destroy failure +> evidence. + +**Unpushed commits row:** + +| Condition | Marker | Text | +|---|---|---| +| `detached==true` | ⚠️ | `detached HEAD at <short_sha>` | +| `upstream==null` | ⚠️ | `` branch `<branch>` has no upstream — set one with `git push -u origin <branch>` `` | +| `upstream!=null`, `ahead==0` | ✓ | `Up to date with origin/<branch>` | +| `upstream!=null`, `ahead>0` | ⚠️ | `` Branch `<branch>` is N commits ahead of origin — push before closing? `` (N = `ahead`) | + +**Sign-off line** (blank line, then this line, after row 8 — or after row 7 if row 8 was omitted): if any of rows 1-8 carries a ⚠️ marker, `✅ Session complete. Safe to close. (Warnings above are advisory — review before closing if relevant.)`; else `✅ Session complete. Safe to close.` + +**Fallback:** malformed/non-object JSON on stdin, or `jq` not installed, or a required key missing → print `SC-FALLBACK: manual — <detail>` and exit 0. `<detail>` is one of: `jq is not installed.`, `malformed checklist JSON.`, or `checklist JSON missing required key '<key>'.` + +- [ ] **Step 1: Write the failing smoke test** + +Create `meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh`: + +```zsh +#!/usr/bin/env zsh +# checklist-assemble.sh smoke test. Hermetic: fixture JSON + a throwaway +# TSV file, no real git state. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +tool="$lib/checklist-assemble.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +run() { print -rn -- "$1" | bash "$tool" "${2:-}"; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +base_json() { + # Minimal valid document: nothing staged/unstaged/untracked, primer + # current, no learnings, no backlog tracked, upstream clean. + cat <<'JSON' +{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false, + "short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current", + "learnings":[],"backlog_mode":"none","backlog_fastpath_count":null, + "commit_subject":null} +JSON +} + +# --- malformed JSON must not crash, must fall back ------------------------- +out="$(run 'not json at all')" +[[ "$out" == SC-FALLBACK:* ]] && ok "malformed JSON -> SC-FALLBACK" \ + || bad "expected SC-FALLBACK, got: $out" + +# --- missing required key must not crash ------------------------------------ +out="$(run '{"staged":[]}')" +[[ "$out" == SC-FALLBACK:* ]] && ok "missing required keys -> SC-FALLBACK, no crash" \ + || bad "expected SC-FALLBACK, got: $out" + +# --- fully clean run: every row ✓, no suggested-commit row, clean sign-off -- +out="$(run "$(base_json)")" +expected="✓ Primer already current (no-op) +✓ No new learnings +✓ Backlog: none tracked +✓ Nothing staged +✓ No unstaged modifications +✓ No untracked files +✓ Up to date with origin/main + +✅ Session complete. Safe to close." +[[ "$out" == "$expected" ]] && ok "fully clean run renders all-✓ checklist, no suggested-commit row, clean sign-off" \ + || bad "got:\n$out" + +# --- new learnings row: singular vs plural ---------------------------------- +one_learning='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[{"number":7,"title":"awk range collapse"}],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$one_learning")" +[[ "$out" == *'✓ 1 LEARNINGS entry captured (#7, "awk range collapse")'* ]] \ + && ok "one learning -> singular 'entry'" \ + || bad "got:\n$out" + +two_learnings='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[{"number":7,"title":"A"},{"number":8,"title":"B"}],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$two_learnings")" +[[ "$out" == *'✓ 2 LEARNINGS entries captured (#7, "A", #8, "B")'* ]] \ + && ok "two learnings -> plural 'entries', both cited" \ + || bad "got:\n$out" + +# --- backlog: fast-path mode ------------------------------------------------- +fastpath='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"fast-path","backlog_fastpath_count":5,"commit_subject":null}' +out="$(run "$fastpath")" +[[ "$out" == *'✓ Backlog: 5 tracked — not re-verified this session (no repo changes since last close-out)'* ]] \ + && ok "fast-path backlog mode renders the standing-count line" \ + || bad "got:\n$out" + +# --- backlog: unavailable / not-migrated modes ------------------------------- +unavail='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"unavailable","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$unavail")" +[[ "$out" == *'✓ Backlog: GitHub queue unavailable — run /session-continuity:doctor'* ]] \ + && ok "unavailable backlog mode renders the doctor pointer" \ + || bad "got:\n$out" + +notmig='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"not-migrated","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$notmig")" +[[ "$out" == *'✓ Backlog: not migrated — run /session-continuity:primer'* ]] \ + && ok "not-migrated backlog mode renders the primer pointer" \ + || bad "got:\n$out" + +# --- backlog: normal mode, mixed verdicts, TSV-driven ------------------------ +tsv="$work/backlog.tsv" +cat <<'TSV' > "$tsv" +#4 appears-DONE found test/end_to_end.bats -> 0 hits before, now present +#3 still-open no *.bats and no test/ dir -> item still open +#5 manual not auto-verifiable +#6 manual no related commits since last refresh -- not re-checked this session +TSV +normal='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"normal","backlog_fastpath_count":null,"commit_subject":null}' +out="$(print -rn -- "$normal" | bash "$tool" "$tsv")" +[[ "$out" == *'⚠️ Backlog: 4 tracked — 1 appears-DONE (#4, "found test/end_to_end.bats -> 0 hits before, now present"), 1 still-open (#3), 2 manual (#5, #6)'* ]] \ + && ok "normal mode tallies all three verdicts, cites only appears-DONE, marks ⚠️" \ + || bad "got:\n$out" +[[ "$out" == *'(Warnings above are advisory'* ]] \ + && ok "any ⚠️ row flips the sign-off line to the advisory variant" \ + || bad "sign-off did not carry the warning suffix:\n$out" + +# --- backlog: normal mode, zero appears-DONE -> ✓, no advisory suffix ------- +cat <<'TSV' > "$tsv" +#3 still-open no *.bats and no test/ dir -> item still open +TSV +out="$(print -rn -- "$normal" | bash "$tool" "$tsv")" +[[ "$out" == *'✓ Backlog: 1 tracked — 1 still-open (#3)'* ]] \ + && ok "normal mode with zero appears-DONE marks ✓, omits the empty appears-DONE clause" \ + || bad "got:\n$out" + +# --- backlog: normal mode, missing TSV path degrades to zero items --------- +out="$(print -rn -- "$normal" | bash "$tool" "$work/does-not-exist.tsv")" +[[ "$out" == *'✓ Backlog: 0 tracked'* ]] \ + && ok "normal mode with an unreadable TSV path degrades to zero tracked, no crash" \ + || bad "got:\n$out" + +# --- backlog: normal mode, citation with embedded quote and backslash ------ +printf '#9\tappears-DONE\tfound "weird" path C:\\temp\\x -> present\n' > "$tsv" +out="$(print -rn -- "$normal" | bash "$tool" "$tsv")" +[[ "$out" == *'1 appears-DONE (#9, "found "weird" path C:\temp\x -> present")'* ]] \ + && ok "citation with embedded quote/backslash renders without breaking JSON parsing" \ + || bad "got:\n$out" + +# --- unrecognized backlog_mode -> SC-FALLBACK, no silent normal-mode fallthrough +bad_mode='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"Normal","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$bad_mode")" +[[ "$out" == SC-FALLBACK:* ]] \ + && ok "unrecognized backlog_mode -> SC-FALLBACK, not silently treated as normal" \ + || bad "got: $out" + +# --- staged/unstaged/untracked rows ------------------------------------------ +files='{"staged":["a.md","b.md"],"unstaged":["c.md"],"untracked":["d.tmp","e.tmp"],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$files")" +[[ "$out" == *'✓ Staged: a.md, b.md'* ]] && ok "staged row lists every file" || bad "got:\n$out" +[[ "$out" == *'⚠️ Unstaged: c.md'* ]] && ok "unstaged row warns and lists" || bad "got:\n$out" +[[ "$out" == *'⚠️ 2 untracked: d.tmp, e.tmp — ignore, add, or delete?'* ]] && ok "untracked row counts and lists" || bad "got:\n$out" + +# --- unpushed commits: all four branch states -------------------------------- +detached='{"staged":[],"unstaged":[],"untracked":[],"branch":"HEAD","detached":true,"short_sha":"deadbee","upstream":null,"ahead":null,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$detached")" +[[ "$out" == *'⚠️ detached HEAD at deadbee'* ]] && ok "detached HEAD row" || bad "got:\n$out" + +noupstream='{"staged":[],"unstaged":[],"untracked":[],"branch":"feature-x","detached":false,"short_sha":"abc1234","upstream":null,"ahead":null,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$noupstream")" +[[ "$out" == *'⚠️ branch `feature-x` has no upstream — set one with `git push -u origin feature-x`'* ]] \ + && ok "no-upstream row" || bad "got:\n$out" + +ahead='{"staged":[],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":3,"primer":"current","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$ahead")" +[[ "$out" == *'⚠️ Branch `main` is 3 commits ahead of origin — push before closing?'* ]] \ + && ok "ahead-of-origin row" || bad "got:\n$out" + +# --- suggested commit: omitted when nothing staged (already covered above) -- +# --- suggested commit: docs-only staged -> literal subject, ignores override - +docs_only='{"staged":[".session-continuity/SESSION_PRIMER.md",".session-continuity/LEARNINGS.md"],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"refreshed","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":"should be ignored"}' +out="$(run "$docs_only")" +[[ "$out" == *'git commit -m "docs: update session continuity"'* ]] \ + && ok "all-docs staged -> literal subject, ignores a supplied commit_subject" \ + || bad "got:\n$out" + +# --- suggested commit: mixed staged, caller-supplied subject used ----------- +mixed='{"staged":[".session-continuity/LEARNINGS.md","hooks/lib/foo.sh"],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"refreshed","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":"fix(ci): extract CHANGELOG section with proper awk range"}' +out="$(run "$mixed")" +[[ "$out" == *'git commit -m "fix(ci): extract CHANGELOG section with proper awk range"'* ]] \ + && ok "mixed staged with a supplied subject -> subject used verbatim" \ + || bad "got:\n$out" + +# --- suggested commit: mixed staged, no subject supplied -> mechanical fallback +mixed_nosubj='{"staged":[".session-continuity/LEARNINGS.md","hooks/lib/foo.sh"],"unstaged":[],"untracked":[],"branch":"main","detached":false,"short_sha":"abc1234","upstream":"origin/main","ahead":0,"primer":"refreshed","learnings":[],"backlog_mode":"none","backlog_fastpath_count":null,"commit_subject":null}' +out="$(run "$mixed_nosubj")" +[[ "$out" == *'git commit -m "chore: update 2 file(s)"'* ]] \ + && ok "mixed staged with no supplied subject -> mechanical N-file fallback, no invented theme" \ + || bad "got:\n$out" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) +``` + +- [ ] **Step 2: Run it to verify it fails** + +```bash +chmod +x meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh +zsh meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh +``` + +Expected: FAIL on every assertion — `hooks/lib/checklist-assemble.sh` does not exist yet. + +- [ ] **Step 3: Write `hooks/lib/checklist-assemble.sh`** + +```bash +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/checklist-assemble.sh — Step 3 checklist renderer for +# /session-continuity:end-session (session-continuity plugin). +# +# Usage: checklist-assemble.sh [<backlog-tsv-path>] +# Reads one JSON object on stdin (see +# meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md +# Task 1 for the full contract) and prints the finished eight-row checklist, +# suggested-commit block, and terminal sign-off line on stdout. Always exits +# 0: a rendering failure must degrade to SC-FALLBACK, never abort the ritual. +# +# <backlog-tsv-path> is read only when the input's backlog_mode=="normal". +# Each line is tag\tverdict\tcitation, one per open backlog item still +# subject to Step 1's overlap gate. A missing/unreadable path in that mode +# degrades to zero tracked items rather than falling back — an empty +# backlog is a valid state, distinct from malformed input. + +set -uo pipefail + +INPUT="$(cat)" +TSV_PATH="${1:-}" + +fallback() { # <detail> + printf 'SC-FALLBACK: manual — %s\n' "$1" + exit 0 +} + +command -v jq >/dev/null 2>&1 || fallback "jq is not installed." + +if ! printf '%s' "$INPUT" | jq -e 'type == "object"' >/dev/null 2>&1; then + fallback "malformed checklist JSON." +fi + +for key in staged unstaged untracked branch primer learnings backlog_mode; do + if ! printf '%s' "$INPUT" | jq -e "has(\"$key\")" >/dev/null 2>&1; then + fallback "checklist JSON missing required key '$key'." + fi +done + +# --- backlog TSV -> a JSON array jq can fold in ------------------------------ +BACKLOG_MODE="$(printf '%s' "$INPUT" | jq -r '.backlog_mode')" +case "$BACKLOG_MODE" in + normal|none|unavailable|not-migrated|fast-path) ;; + *) fallback "unrecognized backlog_mode '$BACKLOG_MODE'." ;; +esac + +BACKLOG_ITEMS_JSON='[]' +if [[ "$BACKLOG_MODE" == "normal" && -n "$TSV_PATH" && -r "$TSV_PATH" ]]; then + # jq's own JSON string encoding handles quotes, backslashes, and control + # characters correctly — no hand-rolled escaping. Split each line on tab; + # a citation containing a literal tab (columns 4+) is rejoined with "\t" + # rather than truncated. + BACKLOG_ITEMS_JSON="$( + jq -R -s ' + split("\n") | map(select(length > 0)) | map(split("\t")) | + map(select(length >= 3)) | + map({tag: .[0], verdict: .[1], citation: (.[2:] | join("\t"))}) + ' "$TSV_PATH" 2>/dev/null + )" + if ! printf '%s' "$BACKLOG_ITEMS_JSON" | jq -e . >/dev/null 2>&1; then + BACKLOG_ITEMS_JSON='[]' + fi +fi + +OUT="$( + printf '%s' "$INPUT" | jq -r --argjson items "$BACKLOG_ITEMS_JSON" ' + # --- row 1: primer ------------------------------------------------------- + def primer_row: + if .primer == "refreshed" then "✓ Primer refreshed and staged" + elif .primer == "closed" then "✓ Primer updated (outstanding item(s) closed)" + else "✓ Primer already current (no-op)" end; + + # --- row 2: learnings ----------------------------------------------------- + def learnings_row: + (.learnings // []) as $l + | if ($l | length) == 0 then "✓ No new learnings" + else + ($l | length) as $n + | (if $n == 1 then "entry" else "entries" end) as $noun + | ([$l[] | "#" + (.number|tostring) + ", \"" + .title + "\""] | join(", ")) as $cited + | "✓ " + ($n|tostring) + " LEARNINGS " + $noun + " captured (" + $cited + ")" + end; + + # --- row 3: backlog --------------------------------------------------------- + def backlog_row: + if .backlog_mode == "none" then {marker:"✓", text:"Backlog: none tracked"} + elif .backlog_mode == "unavailable" then {marker:"✓", text:"Backlog: GitHub queue unavailable — run /session-continuity:doctor"} + elif .backlog_mode == "not-migrated" then {marker:"✓", text:"Backlog: not migrated — run /session-continuity:primer"} + elif .backlog_mode == "fast-path" then {marker:"✓", text:"Backlog: " + (.backlog_fastpath_count|tostring) + " tracked — not re-verified this session (no repo changes since last close-out)"} + else + ($items) as $it + | ($it | length) as $n + | ($it | map(select(.verdict=="appears-DONE"))) as $done + | ($it | map(select(.verdict=="still-open"))) as $open + | ($it | map(select(.verdict=="manual"))) as $man + | ([ + (if ($done|length) > 0 then ($done|length|tostring) + " appears-DONE (" + ([$done[] | .tag + ", \"" + .citation + "\""] | join(", ")) + ")" else empty end), + (if ($open|length) > 0 then ($open|length|tostring) + " still-open (" + ([$open[] | .tag] | join(", ")) + ")" else empty end), + (if ($man|length) > 0 then ($man|length|tostring) + " manual (" + ([$man[] | .tag] | join(", ")) + ")" else empty end) + ] | join(", ")) as $clauses + | {marker: (if ($done|length) > 0 then "⚠️" else "✓" end), + text: "Backlog: " + ($n|tostring) + " tracked" + (if $n > 0 then " — " + $clauses else "" end)} + end; + + # --- rows 4-6: file lists --------------------------------------------------- + def staged_row: + (.staged // []) as $s + | if ($s|length) == 0 then {marker:"✓", text:"Nothing staged"} + else {marker:"✓", text:"Staged: " + ($s|join(", "))} end; + + def unstaged_row: + (.unstaged // []) as $u + | if ($u|length) == 0 then {marker:"✓", text:"No unstaged modifications"} + else {marker:"⚠️", text:"Unstaged: " + ($u|join(", "))} end; + + def untracked_row: + (.untracked // []) as $t + | if ($t|length) == 0 then {marker:"✓", text:"No untracked files"} + else {marker:"⚠️", text:($t|length|tostring) + " untracked: " + ($t|join(", ")) + " — ignore, add, or delete?"} end; + + # --- row 7: unpushed commits ------------------------------------------------- + def unpushed_row: + if .detached == true then + {marker:"⚠️", text:"detached HEAD at " + (.short_sha // "?")} + elif .upstream == null then + {marker:"⚠️", text:"branch `" + .branch + "` has no upstream — set one with `git push -u origin " + .branch + "`"} + elif (.ahead // 0) == 0 then + {marker:"✓", text:"Up to date with " + .upstream} + else + {marker:"⚠️", text:"Branch `" + .branch + "` is " + (.ahead|tostring) + " commits ahead of origin — push before closing?"} + end; + + # --- row 8: suggested commit -------------------------------------------------- + def suggested_row: + (.staged // []) as $s + | if ($s|length) == 0 then null + else + (if ([$s[] | startswith(".session-continuity/")] | all) then "docs: update session continuity" + elif .commit_subject != null then .commit_subject + else "chore: update " + ($s|length|tostring) + " file(s)" end) as $subject + | "→ Suggested:\n```\ngit commit -m \"" + $subject + "\"\n```" + end; + + (primer_row) as $r1 + | (learnings_row) as $r2 + | (backlog_row) as $r3 + | (staged_row) as $r4 + | (unstaged_row) as $r5 + | (untracked_row) as $r6 + | (unpushed_row) as $r7 + | (suggested_row) as $r8 + | [$r1, $r2, ($r3.marker + " " + $r3.text), ($r4.marker + " " + $r4.text), + ($r5.marker + " " + $r5.text), ($r6.marker + " " + $r6.text), + ($r7.marker + " " + $r7.text)] as $rows + | ($rows | map(test("⚠️")) | any) as $any_warn + | ($rows + (if $r8 != null then [$r8] else [] end)) as $all_lines + | ($all_lines | join("\n")) + + "\n\n" + + (if $any_warn then + "✅ Session complete. Safe to close. (Warnings above are advisory — review before closing if relevant.)" + else + "✅ Session complete. Safe to close." + end) + ' 2>/dev/null +)" +JQ_STATUS=$? + +if [[ "$JQ_STATUS" -ne 0 || -z "$OUT" ]]; then + fallback "checklist JSON did not match the expected shape." +fi + +printf '%s\n' "$OUT" +``` + +```bash +chmod +x hooks/lib/checklist-assemble.sh +``` + +- [ ] **Step 4: Run the smoke test to verify all assertions pass** + +```bash +zsh meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh +``` + +Expected: `Result: 23 passed, 0 failed`. If any assertion's exact string doesn't match (jq's `join`/quoting can differ from a hand-written expectation by a stray space), adjust the *test's* expected string to match the script's actual, verified-by-eye-once-correct output — never loosen an assertion's substance (e.g. don't switch an exact `==` to a lax substring match to dodge a real mismatch). + +- [ ] **Step 5: Commit** + +```bash +git add hooks/lib/checklist-assemble.sh meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh +git commit -m "feat: add checklist-assemble.sh, scripting end-session Step 3's row assembly" +``` + +--- + +### Task 2: `perf-log.sh` — gitignore the new scratch TSV + +**Files:** +- Modify: `hooks/lib/perf-log.sh` + +**Interfaces:** +- Modifies: `write_record`'s existing gitignore-ensure loop (the `for LINE in ...` block). No new subcommand, no signature change. + +**Rationale:** Task 3 has `end-session.md` write `.session-continuity/.end-session-checklist.tsv` as scratch state during Step 1, then read-and-delete it at the very start of Step 3's batched Bash call (before the git-status commands run), so it's never actually present when `git status`/`git ls-files --others` runs. The gitignore entry is defense-in-depth for the case where a ritual is interrupted (the user closes the session, or the command errors) between Step 1 writing the file and Step 3 deleting it — without this, an interrupted ritual leaves a stray untracked file in the user's repo. + +- [ ] **Step 1: Add the new path to the existing ensure-loop** + +Using the Edit tool, replace this exact block (currently `hooks/lib/perf-log.sh`, the `for LINE in` line inside `write_record`): + +```bash + for LINE in ".session-continuity/performance.log" ".session-continuity/.gitignore-ensured"; do +``` + +with: + +```bash + for LINE in ".session-continuity/performance.log" ".session-continuity/.gitignore-ensured" ".session-continuity/.end-session-checklist.tsv"; do +``` + +- [ ] **Step 2: Run the existing perf-log smoke test to confirm no regression** + +```bash +zsh meta/superpowers/validation/2026-08-17-perf-log-smoke.zsh +``` + +Expected: `Result: 16 passed, 0 failed` (unchanged — this test doesn't assert on the exact `.gitignore` line set, only on `mark`/`since`/`record` behavior). + +- [ ] **Step 3: Commit** + +```bash +git add hooks/lib/perf-log.sh +git commit -m "chore: gitignore the Step 3 backlog-verdict scratch file" +``` + +--- + +### Task 3: `commands/end-session.md` Step 1 — fast-path count and the backlog-verdict TSV + +**Files:** +- Modify: `commands/end-session.md` (fast path block, currently lines 38-46; backlog verification section, currently lines 59-159) + +**Interfaces:** +- Produces: `.session-continuity/.end-session-checklist.tsv` — one `tag\tverdict\tcitation` line per open backlog item that went through Step 1's classify/verify pass (including overlap-gated and non-code items), written once at the end of the Backlog verification section. Not written at all when `backlog_mode` will be `none`/`unavailable`/`not-migrated`/`fast-path` (the existing skip conditions already cover these — no item list exists to write). +- Consumes: `hooks/lib/backlog-issues.sh --count .` (Task 3's fast-path addition) — already-shipped script, `--count` mode already documented in its own header. + +- [ ] **Step 1: Add a backlog count to the fast path** + +Using the Edit tool, replace this exact block (currently `commands/end-session.md` lines 38-46): + +```markdown +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +git status --porcelain +git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md # <last-primer-commit> +git rev-parse HEAD +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-1-fast-path --duration="$_PERF_DURATION" +``` +``` + +with: + +```markdown +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +git status --porcelain +git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md # <last-primer-commit> +git rev-parse HEAD +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" --count . # <fast-path-backlog-count>, "?" on failure +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-1-fast-path --duration="$_PERF_DURATION" +``` + +`<fast-path-backlog-count>` feeds Step 3's `backlog_fastpath_count`. If it printed `?` (GitHub unavailable), use `backlog_mode="unavailable"` in Step 3 instead of `"fast-path"` — same GitHub-unavailable handling as the non-fast-path skip condition below. +``` + +- [ ] **Step 2: Add the TSV-writing step to Backlog verification** + +Using the Edit tool, insert this new subsection immediately after the "Routing `appears-DONE` candidates" block and before "### Drift check (silent — no user prompt)" in `commands/end-session.md` (i.e. immediately before the current line `### Drift check (silent — no user prompt)`): + +```markdown +**Record every verdict for Step 3.** Once every open item has a verdict +(from the overlap gate, the batched classify/verify pass, or the +non-code default), write them all in **one Bash call**. There is no +in-shell list to loop over — the verdicts exist only in what you just +decided — so write one literal `printf` line per item by hand (not a +shell `for`/`while` loop): + +```bash +mkdir -p .session-continuity +: > .session-continuity/.end-session-checklist.tsv +printf '%s\t%s\t%s\n' "#4" "appears-DONE" "found test/end_to_end.bats -> 0 hits before, now present" >> .session-continuity/.end-session-checklist.tsv +printf '%s\t%s\t%s\n' "#3" "still-open" "no *.bats and no test/ dir -> item still open" >> .session-continuity/.end-session-checklist.tsv +# ... one such literal printf line per remaining open item, tag first (the +# #N identity, never the ephemeral 1..N list position), verdict second +# (still-open|appears-DONE|manual), citation third (the same evidence string +# already decided above — "not auto-verifiable" for non-code items, "no +# related commits since last refresh — not re-checked this session" for +# overlap-gated ones) ... +``` + +Skip this entirely when there were zero open items to classify (the file is +absent; Step 3 treats a missing path under `backlog_mode="normal"` as zero +tracked items — see `hooks/lib/checklist-assemble.sh`'s contract). +``` + +- [ ] **Step 3: Verify the edits landed at the right spots** + +```bash +grep -n 'end-session-checklist.tsv\|fast-path-backlog-count' commands/end-session.md +``` + +Expected: the TSV path appears at least twice (the writing block, the skip note), and `<fast-path-backlog-count>` appears at least twice (the bash comment, the prose sentence after it). + +- [ ] **Step 4: Commit** + +```bash +git add commands/end-session.md +git commit -m "feat: end-session Step 1 records backlog verdicts for the Step 3 checklist script" +``` + +--- + +### Task 4: `commands/end-session.md` Step 3 — call `checklist-assemble.sh` + +**Files:** +- Modify: `commands/end-session.md` (currently lines 409-498: "Gather the facts" through "Example output") + +**Interfaces:** +- Consumes: `hooks/lib/checklist-assemble.sh` (Task 1), resolved via `CLAUDE_PLUGIN_ROOT` and `require_script` (`CONTRACT_VERSION=1`), same convention every other command-invoked script in this file already follows. + +- [ ] **Step 1: Replace "Gather the facts" through "Example output"** + +Using the Edit tool, replace this exact block (currently `commands/end-session.md` lines 409-498, from `## Step 3 — Final checklist` through the `*(Illustrative only ...)*` line): + +````markdown +## Step 3 — Final checklist + +Run real git commands and emit a structured checklist. Every item must reflect actual repo state, not an assertion. + +### Gather the facts + +Run all six in **one Bash call** (one round trip, not six), timed: + +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +git diff --cached --name-only # staged files +git diff --name-only # unstaged modifications +git ls-files --others --exclude-standard # untracked (ignoring .gitignore'd) +git rev-parse --abbrev-ref HEAD # current branch (or "HEAD" if detached) +git rev-parse --abbrev-ref @{u} 2>/dev/null # upstream branch, or empty if none +git rev-list --count @{u}..HEAD 2>/dev/null # unpushed commits, empty if no upstream +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-3-gather-facts --duration="$_PERF_DURATION" +``` + +- **Backlog verdicts** — reuse the per-item verdicts from Step 1's + verification sub-block; re-run + `bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" .` + to get the post-close issue set. No new git command — the evidence was already + gathered in Step 1. + +Handle these edge cases explicitly: + +- **Not a git repo.** If `git rev-parse` fails, the precondition in Step 0 should have caught this, but belt-and-suspenders: report "⚠️ not inside a git repo" once and skip git-dependent rows. +- **Detached HEAD.** `git rev-parse --abbrev-ref HEAD` returns `HEAD`. Note "⚠️ detached HEAD at `<short-sha>`" in the unpushed-commits row. +- **No upstream.** `git rev-parse --abbrev-ref @{u}` fails. Note "⚠️ branch `<name>` has no upstream — set one with `git push -u origin <name>`" in the unpushed-commits row. + +### Emit the checklist + +**List every file enumerated by the git commands — do not summarize, filter, or pick a "primary" one.** If `git diff --cached --name-only` returns three files, the "Staged files" row lists all three. Same rule for the Unstaged and Untracked rows. The suggested-commit message may emphasize one theme, but the checklist rows are inventories, not summaries. + +Output using this structure. Use ✓ (green), ⚠️ (yellow), or → (suggestion): + +| Row | Marker | Content | +|---|---|---| +| Primer refresh | ✓ | "Primer refreshed and staged" OR "Primer updated (outstanding item(s) closed)" OR "Primer already current (no-op)" | +| New learnings | ✓ | "N LEARNINGS entry/entries captured (#X, \"<title>\" …)" OR "No new learnings" | +| Backlog | checkmark if none stale, else warning | "N tracked — <k> appears-DONE (#N, evidence), <m> still-open (#N…), <j> manual (#N…)" OR "none tracked" | +| Staged files | ✓ | "Staged: <file1>, <file2>, …" OR "Nothing staged" | +| Unstaged modifications | ✓ if none, else ⚠️ | "No unstaged modifications" OR "⚠️ Unstaged: <file1>, <file2>, …" | +| Untracked files | ✓ if none, else ⚠️ | "No untracked files" OR "⚠️ N untracked: <file1>, <file2>, … — ignore, add, or delete?" | +| Unpushed commits | ✓ / ⚠️ | "Up to date with origin/<branch>" OR "⚠️ Branch <name> is N commits ahead of origin — push before closing?" OR the detached-HEAD / no-upstream variants | +| Suggested commit | → | Derived from staged files + captured learnings. Omit row entirely if nothing is staged. | + +**Backlog row — re-derive, do not cache.** Step 3 re-runs the helper AFTER any Step 1 closures the +user confirmed. The *set* of issues and the counts are recomputed against the +post-close GitHub list; only the per-item +verdicts (`still-open` / `appears-DONE` / `manual`) computed in Step 1 are +reused. If the user closed an issue at the Step 1 prompt, it is gone from the +list and absent from this row. Marker: ✓ if +every remaining item is `still-open` or `manual` (nothing stale lingering); +⚠️ if any remaining item is `appears-DONE` (a resolved item still listed). +Cite the evidence for each `appears-DONE` item inline. A `manual` item's +citation is either `"not auto-verifiable"` (genuinely non-code) or `"no +related commits since last refresh — not re-checked this session"` (skipped +by the overlap gate) — keep whichever citation Step 1 assigned, don't +collapse them to one phrase. When the fast path fired, skip re-deriving this +row altogether and use its own citation as specified there. + +### Suggested commit message + +If files are staged, derive a commit message from the pattern: + +- Only `.session-continuity/` staged → `docs: update session continuity`. +- `.session-continuity/LEARNINGS.md` is staged with code → pick the most prominent captured learning's title (or the primary code-change theme) and use conventional-commit style: `<type>(<scope>): <subject>`. Keep subject line ≤ 72 chars. +- Only code staged (no docs) → should not happen if Step 1 ran; if it does, suggest based on the file paths. + +Prefix with `→ Suggested:` and wrap in a fenced code block so the user can copy-paste. + +### Example output + +``` +✓ Primer refreshed and staged +✓ 1 LEARNINGS entry captured (#7, "awk range collapse on single-version CHANGELOG") +⚠️ Backlog: 5 tracked — 1 appears-DONE (4 [c7d1], "add bats test harness": found test/end_to_end.bats → 0 hits before, now present), 1 still-open (3 [b092]), 3 manual (1 [a3f9], 2 [7f3e], 5 [e8a4]) +✓ Staged: .session-continuity/SESSION_PRIMER.md, .session-continuity/LEARNINGS.md, .github/workflows/release.yml +✓ No unstaged modifications +⚠️ 2 untracked files: scratch.md, tmp/debug.log — ignore, add, or delete? +⚠️ Branch "main" is 3 commits ahead of origin — push before closing? +→ Suggested: + git commit -m "fix(ci): extract CHANGELOG section with proper awk range" +``` + +*(Illustrative only — the real Backlog row reflects the current primer's actual item set and verdicts.)* +```` + +with: + +````markdown +## Step 3 — Final checklist + +One script call. Every row reflects actual repo state or a value you +decided in Step 1/Step 2 and pass through — never format or re-derive a row +by hand. + +### Gather the facts and render + +Run in **one Bash call**, timed. First, copy the Step 1 scratch TSV to a +location outside the repo and delete the in-repo copy — *before* any +git-status command runs, so the git commands below never see it (its path +can't be deleted-then-read, since `checklist-assemble.sh` needs to read it +after the git commands run; copying it out first is what makes both true +at once). Task 2's gitignore entry is the separate belt-and-suspenders case: +a ritual that crashes *before* this block ever runs leaves the file +in-repo, and only the gitignore entry (not this ordering) keeps it out of +a later `git ls-files --others`. Then run the seven git commands, then +build the JSON `checklist-assemble.sh` expects and pipe it through: + +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +TSV_INREPO=".session-continuity/.end-session-checklist.tsv" +TSV="" +if [[ -r "$TSV_INREPO" ]]; then + TSV="$(mktemp)" + cp "$TSV_INREPO" "$TSV" + rm -f "$TSV_INREPO" +fi +BACKLOG_MODE="normal" # set to none|unavailable|not-migrated|fast-path per Step 1's skip conditions/fast path instead, when applicable +BACKLOG_FASTPATH_COUNT="null" # the fast path's <fast-path-backlog-count>, only when BACKLOG_MODE=fast-path + +STAGED_JSON="$(git diff --cached --name-only | jq -R -s 'split("\n") | map(select(length>0))')" +UNSTAGED_JSON="$(git diff --name-only | jq -R -s 'split("\n") | map(select(length>0))')" +UNTRACKED_JSON="$(git ls-files --others --exclude-standard | jq -R -s 'split("\n") | map(select(length>0))')" +BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo HEAD)" +if [[ "$BRANCH" == "HEAD" ]]; then DETACHED=true; else DETACHED=false; fi +SHORT_SHA="$(git rev-parse --short HEAD 2>/dev/null || echo '?')" +UPSTREAM="$(git rev-parse --abbrev-ref @{u} 2>/dev/null || true)" +if [[ -z "$UPSTREAM" ]]; then UPSTREAM_JSON="null"; AHEAD_JSON="null"; else + UPSTREAM_JSON="$(printf '%s' "$UPSTREAM" | jq -R .)" + AHEAD="$(git rev-list --count @{u}..HEAD 2>/dev/null || echo 0)" + AHEAD_JSON="$AHEAD" +fi + +# PRIMER, LEARNINGS_JSON, COMMIT_SUBJECT_JSON: set these three from what +# Step 1/Step 2 actually did this invocation — see the field notes below. +PRIMER="current" # "refreshed" | "closed" | "current" +LEARNINGS_JSON="[]" # e.g. '[{"number":7,"title":"..."}]' from Step 2's captures +COMMIT_SUBJECT_JSON="null" # a quoted JSON string, or "null", per the field note below + +JSON_TMP="$(mktemp)" +jq -n \ + --argjson staged "$STAGED_JSON" --argjson unstaged "$UNSTAGED_JSON" \ + --argjson untracked "$UNTRACKED_JSON" --arg branch "$BRANCH" \ + --argjson detached "$DETACHED" --arg short_sha "$SHORT_SHA" \ + --argjson upstream "$UPSTREAM_JSON" --argjson ahead "$AHEAD_JSON" \ + --arg primer "$PRIMER" --argjson learnings "$LEARNINGS_JSON" \ + --arg backlog_mode "$BACKLOG_MODE" --argjson backlog_fastpath_count "$BACKLOG_FASTPATH_COUNT" \ + --argjson commit_subject "$COMMIT_SUBJECT_JSON" \ + '{staged:$staged, unstaged:$unstaged, untracked:$untracked, branch:$branch, + detached:$detached, short_sha:$short_sha, upstream:$upstream, ahead:$ahead, + primer:$primer, learnings:$learnings, backlog_mode:$backlog_mode, + backlog_fastpath_count:$backlog_fastpath_count, commit_subject:$commit_subject}' \ + > "$JSON_TMP" + +source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/checklist-assemble.sh" 1; then + CHECKLIST="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/checklist-assemble.sh" "$TSV" < "$JSON_TMP")" +else + CHECKLIST="⚠️ $SC_REQUIRE_SCRIPT_MSG" +fi +rm -f "$TSV" "$JSON_TMP" + +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-3-gather-facts --duration="$_PERF_DURATION" +echo "$CHECKLIST" +``` + +**Field notes — the values only you know, filled in before running the block above:** + +- `BACKLOG_MODE` / `BACKLOG_FASTPATH_COUNT`: `"fast-path"` + the fast path's `<fast-path-backlog-count>` when Step 1's fast path fired; otherwise whichever of `none`/`unavailable`/`not-migrated`/`normal` Step 1's Backlog verification section landed on (its own skip conditions already tell you which). +- `TSV`: leave as computed above (empty string unless the in-repo scratch file existed and was copied out before deletion) — never override it by hand. +- `PRIMER`: `"refreshed"` if the refresh flow ran and staged the primer, `"closed"` if only the drift-clean close-candidate prompt ran and closed item(s), `"current"` if Step 1 was a no-op (fast path or drift-clean-zero-candidates). +- `LEARNINGS_JSON`: the accepted drafts from Step 2's capture flow, as `[{"number":N,"title":"..."}]`; `[]` if Step 2 captured nothing. +- `COMMIT_SUBJECT_JSON`: `"null"` (the bare word, unquoted) unless staged files exist AND at least one is outside `.session-continuity/` — in that case, a quoted JSON string with your conventional-commit subject (`<type>(<scope>): <subject>`, ≤72 chars), e.g. `'"fix(ci): extract CHANGELOG section with proper awk range"'`. Pick the theme from the most prominent captured learning's title, or the primary code-change theme — same judgment call as before this phase, just handed to the script instead of formatted by hand. + +**Output.** If `$CHECKLIST` starts with `⚠️` (the `require_script` failure) or `SC-FALLBACK:` (the script's own malformed-input escape), print it as a single warning line and assemble the checklist by hand this one time, following the row table that existed before this phase (Primer refresh / New learnings / Backlog / Staged files / Unstaged modifications / Untracked files / Unpushed commits / Suggested commit, each ✓/⚠️/→, backlog citing evidence for `appears-DONE` only) — then still emit Step 4's sign-off line yourself, choosing the warning-suffixed variant if any row you assembled carries ⚠️. Otherwise, print `$CHECKLIST` verbatim — it already ends with the terminal sign-off line; do not print anything after it except whatever Step 4's timing calls require. +```` + +- [ ] **Step 2: Verify the old prose-formatting table and example are gone** + +```bash +grep -c 'List every file enumerated\|Illustrative only' commands/end-session.md +``` + +Expected: `0`. + +- [ ] **Step 3: Commit** + +```bash +git add commands/end-session.md +git commit -m "refactor: end-session Step 3 renders the checklist via checklist-assemble.sh" +``` + +--- + +### Task 5: `commands/end-session.md` Step 4 — drop the printed sign-off, keep only timing + +**Files:** +- Modify: `commands/end-session.md` (currently lines 500-569: `## Step 4 — Terminal sign-off (always)` through the "Required." paragraph) + +**Interfaces:** +- Consumes: nothing new — Step 4's two timing blocks (`step-4-ritual-complete`, `step-4-agent-active`) are unchanged. +- Produces: nothing printed — Task 4's `$CHECKLIST` already ends with the sign-off line. Step 4 becomes purely a logging step with no user-facing output of its own. + +- [ ] **Step 1: Replace the section header and the two "Always emit" bullets** + +Using the Edit tool, replace this exact block (currently `commands/end-session.md` lines 500-502): + +```markdown +## Step 4 — Terminal sign-off (always) + +After the checklist (and suggested-commit block, if any), emit a final closing line so the user knows the ritual completed and they are not blocked waiting for further prompts. +``` + +with: + +```markdown +## Step 4 — Ritual timing (always) + +Step 3's `$CHECKLIST` already ended with the terminal sign-off line — this +step prints nothing of its own. It only logs how long the ritual took, so +the log carries one real end-to-end number per invocation. +``` + +- [ ] **Step 2: Delete the "Always emit one of these two lines" block and its two example lines** + +Using the Edit tool, replace this exact block (currently `commands/end-session.md` lines 555-569): + +```markdown +**Always emit one of these two lines, exactly:** + +- If every checklist row was ✓ (no ⚠️ anywhere): + + ``` + ✅ Session complete. Safe to close. + ``` + +- If any checklist row had ⚠️: + + ``` + ✅ Session complete. Safe to close. (Warnings above are advisory — review before closing if relevant.) + ``` + +**Required.** Print this line on its own, after the checklist and any suggested-commit block. Never omit it. Never replace it with paraphrased prose. Never ask follow-up questions after this line — the line marks the end of the ritual. If the user wants to act on a warning, they will reply on their own. +``` + +with: + +```markdown +**Never ask follow-up questions after Step 3's sign-off line printed.** It marks the end of the ritual. If the user wants to act on a warning, they will reply on their own. +``` + +- [ ] **Step 3: Verify no duplicate sign-off text remains** + +```bash +grep -c '✅ Session complete' commands/end-session.md +``` + +Expected: `0` — the two literal sign-off strings now live only inside `checklist-assemble.sh` and this plan's own smoke test, not in the command markdown. + +- [ ] **Step 4: Commit** + +```bash +git add commands/end-session.md +git commit -m "refactor: end-session Step 4 becomes a pure timing step, sign-off now owned by checklist-assemble.sh" +``` + +--- + +### Task 6: Doc pointers, regression pass, changelog + +**Files:** +- Modify: `meta/superpowers/specs/2026-09-02-determinism-program-design.md` +- Modify: `CHANGELOG.md` + +- [ ] **Step 1: Collapse the design doc's Phase 4 entry to a pointer** + +Using the Edit tool, replace this exact block in `meta/superpowers/specs/2026-09-02-determinism-program-design.md`: + +```markdown +**Phase 4 `#41` — `end-session` Step 3 checklist assembly.** One script consuming the +six git outputs and a `tag<TAB>verdict<TAB>citation` file, emitting the eight +finished rows, the four backlog tallies, the per-row markers, and the sign-off +boolean (612-675, 759-773), retiring the example block at 687-701. Depends on +Phase 3's `since`. Removes the file-inventory summarization failure that +line 646 exists to prevent. +``` + +with: + +```markdown +**Phase 4 `#41` — `end-session` Step 3 checklist assembly.** `checklist-assemble.sh` +consumes the (now seven — a `git rev-parse --short HEAD` was added for the +detached-HEAD row) git outputs plus a `tag<TAB>verdict<TAB>citation` scratch +file, emitting all eight finished rows, the backlog tallies, every marker, +and the terminal sign-off line as one block — Step 4 no longer prints +anything of its own. Removes the "list every file, do not summarize" +instruction and the illustrative example entirely; the script's own output +is the contract. Plan: +`meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md`. +``` + +- [ ] **Step 2: Full regression pass** + +```bash +for f in \ + meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh \ + meta/superpowers/validation/2026-08-17-perf-log-smoke.zsh \ + meta/superpowers/validation/2026-09-03-primer-status-smoke.zsh \ + meta/superpowers/validation/2026-08-12-session-start-smoke.zsh \ + meta/superpowers/validation/2026-09-01-require-script-smoke.zsh \ + meta/superpowers/validation/2026-09-01-agent-active-smoke.zsh \ + meta/superpowers/validation/2026-09-02-resolve-transcript-smoke.zsh \ + meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh \ + meta/superpowers/validation/2026-09-02-candidate-render-smoke.zsh \ + meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh +do + echo "--- $f ---" + zsh "$f" || echo "FAILED: $f" +done +``` + +Expected: every runner ends `0 failed`. + +- [ ] **Step 3: Add a CHANGELOG entry** + +Add a new section at the top of `CHANGELOG.md`, directly under the `# Changelog` header and its description line, above `## [0.29.1]`: + +```markdown +## [0.30.0] — 2026-09-08 + +### Changed +- **`end-session`'s Step 3 checklist is now scripted.** New `hooks/lib/checklist-assemble.sh` consumes the seven git-status outputs and a `tag/verdict/citation` backlog-verdict file, and prints all eight finished checklist rows, the backlog tallies, every ✓/⚠️ marker, the suggested-commit block, and the terminal sign-off line as one deterministic block. The model's job shrinks to deciding backlog verdicts (unchanged from before) and picking a commit-message theme when code is staged — everything else (file-list rendering, tallying, marker selection, sign-off wording) is no longer hand-formatted per invocation. Step 4 no longer prints anything; the sign-off line is now part of Step 3's script output. +``` + +- [ ] **Step 4: Bump the plugin version** + +Using the Edit tool, update `.claude-plugin/plugin.json`'s `"version"` field from `"0.29.1"` to `"0.30.0"`. + +- [ ] **Step 5: Commit** + +```bash +git add meta/superpowers/specs/2026-09-02-determinism-program-design.md CHANGELOG.md .claude-plugin/plugin.json +git commit -m "docs: Phase 4 doc pointers, changelog, and version bump for the checklist script" +``` diff --git a/meta/superpowers/plans/2026-09-09-test-count-rerun.md b/meta/superpowers/plans/2026-09-09-test-count-rerun.md new file mode 100644 index 0000000..28ac671 --- /dev/null +++ b/meta/superpowers/plans/2026-09-09-test-count-rerun.md @@ -0,0 +1,695 @@ +# Determinism Phase 6, sub-project B — `test-count-rerun.sh`/`.jq` Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace `commands/primer.md` Step 4 item 3 (the test-count majority-vote rerun that runs during Refresh mode) with one script, `hooks/lib/test-count-rerun.sh`, that reads the recorded test count back from `PROJECT_CONTEXT.md`, decides whether/how many times to rerun the test command, and prints a definitive `MODE`/`DRIFT`/`PINNED_COUNT`/`SPREAD` verdict. + +**Architecture:** `test-count-rerun.sh` (bash, I/O — parses `PROJECT_CONTEXT.md`'s `TEST_COMMAND_SUMMARY` line, runs the git-diff skip check, executes the test command 0-3 times per the existing match-then-retry rule) hands the collected observations to `test-count-rerun.jq` (pure decision function — no I/O, fixture-testable with synthetic JSON) for the majority-vote/drift/spread computation. The `.jq` filter's vote algorithm is mode-agnostic: it derives every output field generically from `{mode, recorded, observed}`, so `skip`/`no-command`/`no-count`'s "always empty/zero" outputs fall out of the same generic logic applied to a 0- or 1-element `observed` array, rather than needing special-cased branches per mode. + +**Tech Stack:** Bash, `jq` (already a hard dependency across this plugin), zsh (smoke tests only). + +**Spec:** `meta/superpowers/specs/2026-09-09-test-count-rerun-design.md`. That spec was corrected once during writing (caveman-review found the `run-unparseable` mode conflated "dispatch mode" with "internal outcome," an underspecified majority rule when a run is unparseable, an undocumented `N`-vs-`M` comparison choice, and a testing-list gap) — all four fixes are already folded into the spec text; this plan implements it as it now reads. + +## Global Constraints + +- `test-count-rerun.sh` and `test-count-rerun.jq` both carry a `# CONTRACT_VERSION=1` header. `commands/primer.md` calls the `.sh` through `require_script`, exactly like `primer-detect.sh` already is in Step 1 and `primer-status.sh` in Step 5. `test-count-rerun.sh` itself checks its sibling `.jq`'s `CONTRACT_VERSION` before invoking it, exactly like `primer-detect.sh` does. +- **No fabricated verdict on operational failure.** jq missing, the `.jq` filter missing/version-mismatched, or `PROJECT_CONTEXT.md` unreadable each print one diagnostic line to stderr and exit nonzero with no `MODE=` line on stdout. Unlike `primer-detect.sh`, a wrong guess here is not destructive (no `git mv`/`git rm` downstream), but `commands/primer.md` still must not invent a drift verdict on failure — it falls back to `TBD`/manual reporting. +- **Never invent a test count.** `RECORDED_COUNT`/`OBSERVED` entries are either a real parsed integer or empty/`null` — this plan changes *how* the rerun decision is computed, never invents a count `PROJECT_CONTEXT.md` or a test run didn't actually produce. +- All vote/drift/spread decision logic lives in `test-count-rerun.jq`; `test-count-rerun.sh`'s only jobs are parsing `PROJECT_CONTEXT.md`, the skip check, and running the test command the right number of times. +- Only `<TEST_CMD>`'s pass count (`N`) round-trips for drift comparison. The fail count (`M`), when present in `PROJECT_CONTEXT.md`'s `N pass / M fail` line, is not parsed or compared by this script — an inherited limitation from the current prose, not introduced here (see spec's "Recorded-count format" section). +- Do not touch `commands/primer.md` Step 4 items 1, 2, 4, 5, 6, 7, 8, or Step 2's inline placeholder-derivation prose (sub-project D's scope) — this plan only replaces item 3. +- Do not touch `hooks/lib/primer-detect.sh`/`.jq` (sub-project A, already shipped) or `hooks/lib/token-overlap.sh`/`.jq` (Phase 5, already shipped) — unrelated to this plan. + +--- + +## File Structure + +| File | Responsibility | +|---|---| +| `hooks/lib/test-count-rerun.jq` (new) | Pure decision function: given `{mode, recorded, observed}`, computes `RETRIES`, `UNPARSEABLE`, `DRIFT`, `PINNED_COUNT`, `SPREAD` and prints the full `KEY=value` block (including pass-through fields). No I/O. | +| `hooks/lib/test-count-rerun.sh` (new) | I/O: parses `PROJECT_CONTEXT.md`'s Test-expectations section for `TEST_CMD`/`RECORDED_COUNT`, runs the git-diff skip check, executes `TEST_CMD` 0-3 times per mode, invokes the filter. | +| `commands/primer.md` (modified) | Step 4 item 3's ~8-line prose collapses to one script call plus a short per-`MODE` reporting table. | +| `meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh` (new) | Smoke test: `.jq`-only fixtures (synthetic JSON, no git/subprocess) plus `.sh` integration fixtures (scratch git repos with a fake, invocation-counted `TEST_CMD`) plus operational-failure cases. | +| `meta/superpowers/specs/2026-09-02-determinism-program-design.md` (modified) | Phase 6 entry notes sub-project B shipped; C/D/E remain listed as pending. | +| `CHANGELOG.md` (modified) | New version entry. | +| `.claude-plugin/plugin.json` (modified) | Version bump `0.32.0` → `0.33.0`. | + +--- + +### Task 1: `hooks/lib/test-count-rerun.jq` + `hooks/lib/test-count-rerun.sh` + +**Files:** +- Create: `hooks/lib/test-count-rerun.jq` +- Create: `hooks/lib/test-count-rerun.sh` +- Test: `meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh` + +**Interfaces:** +- Produces: `bash test-count-rerun.sh <project-dir> <last-primer-commit>`. Prints `KEY=value` lines to stdout, ending in the fields listed in the spec's Output contract (`TEST_CMD`, `RECORDED_COUNT`, `MODE`, `RETRIES`, `OBSERVED`, `UNPARSEABLE`, `DRIFT`, `PINNED_COUNT`, `SPREAD`). Exits 0 on success. On operational failure, prints one diagnostic line to stderr and exits 1 with **no** `MODE=` line anywhere in stdout. +- Consumes: `jq` (hard dependency), `git`, `timeout` (GNU coreutils — already assumed elsewhere in this plugin, e.g. Step 2's init test run). + +**Extraction-format note (read before writing tests):** `PROJECT_CONTEXT.md`'s `{{TEST_COMMAND_SUMMARY}}` placeholder is seeded by Step 2 as `` `<TEST_CMD>` — N pass / M fail `` (backtick-wrapped command, then an em dash, then the counts), or freeform prose (this repo's own file: "No automated test suite. Validation is manual: ..."), or a bare fallback string, or `TBD`. This script only ever treats the line as having a real `TEST_CMD` when it starts with a backtick-quoted command — any other content (freeform prose, `TBD`, missing section) is `MODE=no-command` with `TEST_CMD` empty. This is the conservative direction: never invent a command to execute from prose that wasn't written as one. + +**jq mode-agnostic vote design (read before writing tests):** the `.jq` filter takes `$mode` (string, pass-through only — it does not gate any branch), `$recorded` (int or `null`), and `$observed` (JSON array of ints and/or `null`s, one entry per run actually executed — `null` means that run produced no parseable count). It computes `RETRIES` from `$observed`'s length, the parseable subset (dropping `null`s) for voting, `PINNED_COUNT` as the parseable value with ≥2 occurrences (or empty if none), `SPREAD` as "no value pinned but ≥2 distinct parseable values exist," and `DRIFT` as "a value was pinned and it differs from `$recorded`." A 0- or 1-element `$observed` (the `skip`/`no-command`/`no-count` cases, and the "matched on first try" case) can never produce a pinned majority by construction, so `DRIFT`/`SPREAD` fall out as `0` automatically — no per-mode special casing needed inside the filter. + +- [ ] **Step 1: Write the failing smoke test** + +Create `meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh`: + +```zsh +#!/usr/bin/env zsh +# test-count-rerun.sh/.jq smoke test. Two layers: +# Part A: .jq fixtures via synthetic JSON (no git, no subprocess) -- the +# vote/drift/spread/unparseable matrix. +# Part B: .sh integration fixtures via scratch git repos with a fake, +# invocation-counted TEST_CMD -- the skip check, the +# extraction format, and the match-then-retry run count. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +jq_filter="$lib/test-count-rerun.jq" +tool="$lib/test-count-rerun.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +# --------------------------------------------------------------------------- +# Part A: .jq fixtures +# --------------------------------------------------------------------------- + +jq_run() { # <mode> <recorded-json> <observed-json> -> full KEY=value output + # --arg test_cmd "" is required even though these fixtures don't care + # about TEST_CMD's value: jq errors at compile time on an unbound $var, + # it does not treat a never-passed --arg as null, so the filter's own + # "$test_cmd // \"\"" guard never gets a chance to run without this. + jq -r -n --arg mode "$1" --argjson recorded "$2" --argjson observed "$3" --arg test_cmd "" -f "$jq_filter" +} +jq_field() { # <output> <KEY> -> value + print -r -- "$1" | awk -F= -v k="$2" '$1==k{print substr($0, length(k)+2)}' +} + +# A1: skip mode, empty observed -> all zeros +out="$(jq_run skip null '[]')" +[[ "$(jq_field "$out" MODE)" == "skip" && "$(jq_field "$out" RETRIES)" == "0" \ + && "$(jq_field "$out" DRIFT)" == "0" && "$(jq_field "$out" SPREAD)" == "0" \ + && "$(jq_field "$out" UNPARSEABLE)" == "0" ]] \ + && ok "A1: skip -> all zeros" || bad "A1: got '$out'" + +# A2: match on first run -> no drift, no pin (only 1 observation) +out="$(jq_run run 1162 '[1162]')" +[[ "$(jq_field "$out" DRIFT)" == "0" && "$(jq_field "$out" PINNED_COUNT)" == "" \ + && "$(jq_field "$out" RETRIES)" == "0" ]] \ + && ok "A2: first-run match -> no drift, unpinned" || bad "A2: got '$out'" + +# A3: 2-of-3 majority confirms drift +out="$(jq_run run 1162 '[1161,1161,1162]')" +[[ "$(jq_field "$out" PINNED_COUNT)" == "1161" && "$(jq_field "$out" DRIFT)" == "1" \ + && "$(jq_field "$out" SPREAD)" == "0" && "$(jq_field "$out" RETRIES)" == "2" ]] \ + && ok "A3: 2-of-3 majority -> drift confirmed" || bad "A3: got '$out'" + +# A4: 2-of-3 majority matches recorded -> first run was the flake, no drift +out="$(jq_run run 1162 '[1161,1162,1162]')" +[[ "$(jq_field "$out" PINNED_COUNT)" == "1162" && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A4: 2-of-3 majority matches recorded -> no drift" || bad "A4: got '$out'" + +# A5: all 3 disagree -> spread, no pin, no drift +out="$(jq_run run 1162 '[1160,1161,1162]')" +[[ "$(jq_field "$out" SPREAD)" == "1" && "$(jq_field "$out" PINNED_COUNT)" == "" \ + && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A5: 3-way disagreement -> spread" || bad "A5: got '$out'" + +# A6: 2 parseable disagree + 1 unparseable -> spread (not a false no-drift) +out="$(jq_run run 1162 '[1161,null,1162]')" +[[ "$(jq_field "$out" SPREAD)" == "1" && "$(jq_field "$out" UNPARSEABLE)" == "1" \ + && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A6: 2 disagree + 1 unparseable -> spread" || bad "A6: got '$out'" + +# A7: 2-of-2 parseable agree, 3rd unparseable -> majority still pins +out="$(jq_run run 1162 '[1161,null,1161]')" +[[ "$(jq_field "$out" PINNED_COUNT)" == "1161" && "$(jq_field "$out" DRIFT)" == "1" \ + && "$(jq_field "$out" SPREAD)" == "0" && "$(jq_field "$out" UNPARSEABLE)" == "1" ]] \ + && ok "A7: 2-of-2 parseable agree (3rd unparseable) -> pinned" || bad "A7: got '$out'" + +# A8: all 3 unparseable -> no pin, no spread, UNPARSEABLE=1 +out="$(jq_run run 1162 '[null,null,null]')" +[[ "$(jq_field "$out" UNPARSEABLE)" == "1" && "$(jq_field "$out" SPREAD)" == "0" \ + && "$(jq_field "$out" PINNED_COUNT)" == "" && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A8: all 3 unparseable -> no pin, no spread" || bad "A8: got '$out'" + +# A9: no-count mode, single run, no recorded value -> never drifts +out="$(jq_run no-count null '[1162]')" +[[ "$(jq_field "$out" DRIFT)" == "0" && "$(jq_field "$out" SPREAD)" == "0" \ + && "$(jq_field "$out" RECORDED_COUNT)" == "" ]] \ + && ok "A9: no-count -> never drifts, recorded stays empty" || bad "A9: got '$out'" + +# A10: no-command mode, no observations +out="$(jq_run no-command null '[]')" +[[ "$(jq_field "$out" MODE)" == "no-command" && "$(jq_field "$out" RETRIES)" == "0" ]] \ + && ok "A10: no-command -> zero retries" || bad "A10: got '$out'" + +# --------------------------------------------------------------------------- +# Part B: .sh integration fixtures +# --------------------------------------------------------------------------- + +# mk_repo <dir> <summary-line> -> scratch repo with PROJECT_CONTEXT.md's Test +# expectations section set to <summary-line>, committed, primer touched at +# HEAD (so <last-primer-commit> == HEAD unless the caller commits more after). +mk_repo() { + local dir="$1" summary="$2" + rm -rf "$dir"; mkdir -p "$dir/.session-continuity" + git -C "$dir" init -q + git -C "$dir" config user.email test@example.com + git -C "$dir" config user.name Test + print -r -- "# Context + +## Test expectations — these must stay green + +$summary + +## End-to-end check +" > "$dir/.session-continuity/PROJECT_CONTEXT.md" + print -r -- "# Primer" > "$dir/.session-continuity/SESSION_PRIMER.md" + git -C "$dir" add -A + git -C "$dir" commit -qm init +} + +# fake_cmd <dir> <counter-file> <sequence...> -> writes a TEST_CMD script at +# <dir>/fake-test.sh that pops one value off <sequence> per invocation +# (appending its own PID-independent invocation count to <counter-file>) and +# echoes "<value> pass" (or nothing, for a deliberately unparseable run, +# encoded as the literal token "UNPARSEABLE"). +fake_cmd() { + local dir="$1" counter="$2"; shift 2 + : > "$counter" + print -r -- '#!/usr/bin/env bash' > "$dir/fake-test.sh" + print -r -- "seq=($*)" >> "$dir/fake-test.sh" + cat >> "$dir/fake-test.sh" <<'EOF' +n=$(wc -l < "$COUNTER_FILE") +val="${seq[$n]}" +echo "run" >> "$COUNTER_FILE" +if [[ "$val" == "UNPARSEABLE" ]]; then + echo "no count here" +else + echo "$val pass" +fi +EOF + chmod +x "$dir/fake-test.sh" +} + +last_commit() { git -C "$1" log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md; } + +# B1: skip mode -- only .session-continuity/ files changed since last primer touch +d="$work/b1"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +lc="$(last_commit "$d")" +print -r -- x >> "$d/.session-continuity/LEARNINGS.md" +git -C "$d" add -A; git -C "$d" commit -qm "docs only" +out="$(cd "$d" && bash "$tool" "$d" "$lc" 2>&1)" +[[ "$out" == *"MODE=skip"* ]] && ok "B1: docs-only change -> skip" || bad "B1: got '$out'" + +# B2: no-command mode -- freeform prose, no backtick-quoted command +d="$work/b2"; mk_repo "$d" 'No automated test suite. Validation is manual.' +lc="$(last_commit "$d")" +out="$(cd "$d" && bash "$tool" "$d" "$lc" 2>&1)" +[[ "$(jq_field "$out" MODE)" == "no-command" && "$(jq_field "$out" TEST_CMD)" == "" ]] \ + && ok "B2: freeform prose -> no-command, empty TEST_CMD" || bad "B2: got '$out'" + +# B3: no-count mode -- backtick command present, no parseable count +d="$work/b3"; mk_repo "$d" '`./fake-test.sh`' +fake_cmd "$d" "$d/counter" "3" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$(last_commit "$d")" 2>&1)" +[[ "$(jq_field "$out" MODE)" == "no-count" ]] && ok "B3: bare command, no count -> no-count" || bad "B3: got '$out'" + +# B4: run mode, first-run match -> exactly 1 invocation, no drift +d="$work/b4"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +fake_cmd "$d" "$d/counter" "3" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$(last_commit "$d")" 2>&1)" +invocations="$(wc -l < "$d/counter" | tr -d ' ')" +[[ "$(jq_field "$out" MODE)" == "run" && "$(jq_field "$out" DRIFT)" == "0" && "$invocations" == "1" ]] \ + && ok "B4: first-run match -> 1 invocation, no drift" || bad "B4: got '$out' (invocations=$invocations)" + +# B5: run mode, first-run mismatch -> retries to 3, drift confirmed +d="$work/b5"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +fake_cmd "$d" "$d/counter" "4" "4" "4" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$(last_commit "$d")" 2>&1)" +invocations="$(wc -l < "$d/counter" | tr -d ' ')" +[[ "$(jq_field "$out" DRIFT)" == "1" && "$(jq_field "$out" PINNED_COUNT)" == "4" && "$invocations" == "3" ]] \ + && ok "B5: mismatch -> 3 invocations, drift confirmed" || bad "B5: got '$out' (invocations=$invocations)" + +# B6: run mode, all 3 runs unparseable -> well-formed OBSERVED, no crash +d="$work/b6"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +fake_cmd "$d" "$d/counter" "UNPARSEABLE" "UNPARSEABLE" "UNPARSEABLE" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$(last_commit "$d")" 2>&1)" +[[ "$out" == *"UNPARSEABLE=1"* && "$out" == *"OBSERVED=,,"* ]] \ + && ok "B6: all 3 unparseable -> well-formed OBSERVED, UNPARSEABLE=1" || bad "B6: got '$out'" + +# --------------------------------------------------------------------------- +# Operational failure cases +# --------------------------------------------------------------------------- + +# B7: missing .jq filter +d="$work/b7"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +badlib="$work/badlib"; mkdir -p "$badlib"; cp "$tool" "$badlib/" +out="$(bash "$badlib/test-count-rerun.sh" "$d" "$(last_commit "$d")" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"MODE="* ]] \ + && ok "B7: missing filter -> nonzero exit, no MODE= line" || bad "B7: rc=$rc out='$out'" + +# B8: wrong CONTRACT_VERSION +d="$work/b8"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +wronglib="$work/wronglib"; mkdir -p "$wronglib"; cp "$tool" "$wronglib/" +sed 's/CONTRACT_VERSION=1/CONTRACT_VERSION=99/' "$jq_filter" > "$wronglib/test-count-rerun.jq" +out="$(bash "$wronglib/test-count-rerun.sh" "$d" "$(last_commit "$d")" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"MODE="* ]] \ + && ok "B8: wrong CONTRACT_VERSION -> nonzero exit, no MODE= line" || bad "B8: rc=$rc out='$out'" + +# B9: jq absent from PATH +d="$work/b9"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +nojq="$work/nojq"; mkdir -p "$nojq/bin" +for b in bash git awk grep sed head cat mktemp dirname timeout wc tr; do + p="$(command -v "$b")"; [[ -n "$p" ]] && ln -sf "$p" "$nojq/bin/$b" +done +out="$(PATH="$nojq/bin" bash "$tool" "$d" "$(last_commit "$d")" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"MODE="* ]] \ + && ok "B9: jq absent from PATH -> nonzero exit, no MODE= line" || bad "B9: rc=$rc out='$out'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) +``` + +- [ ] **Step 2: Run it to verify it fails** + +```bash +chmod +x meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh +``` + +Expected: FAIL on every assertion — neither `hooks/lib/test-count-rerun.jq` nor `hooks/lib/test-count-rerun.sh` exists yet. + +- [ ] **Step 3: Write `hooks/lib/test-count-rerun.jq`** + +```jq +# CONTRACT_VERSION=1 +# hooks/lib/test-count-rerun.jq — pure vote/drift/spread decision for +# /session-continuity:primer Step 4's test-count rerun. Invoked via +# test-count-rerun.sh; see that file for the CLI contract and +# meta/superpowers/specs/2026-09-09-test-count-rerun-design.md for the +# full output contract this implements. +# +# Mode-agnostic by design: $mode is pass-through only (it never gates a +# branch here). skip/no-command/no-count's "always empty" outputs fall +# out of running this same algorithm against a 0- or 1-element $observed +# array — see the design spec's "MODE=run" outcomes table for why a +# majority can never be pinned from fewer than 2 parseable votes. + +($observed | length) as $n +| ($observed | map(select(. != null))) as $parseable +| (if $n == 0 then 0 else $n - 1 end) as $retries +| (any($observed[]; . == null)) as $unparseable +| ($parseable | group_by(.) | map({value: .[0], count: length}) + | map(select(.count >= 2))) as $majority +| ($majority[0].value // null) as $pinned +| (if $pinned != null then false + else ($parseable | unique | length) >= 2 + end) as $spread +| ($pinned != null and $recorded != null and $pinned != $recorded) as $drift + +| "TEST_CMD=" + ($test_cmd // ""), + "RECORDED_COUNT=" + (if $recorded == null then "" else ($recorded|tostring) end), + "MODE=" + $mode, + "RETRIES=" + ($retries|tostring), + "OBSERVED=" + ($observed | map(if . == null then "" else (.|tostring) end) | join(",")), + "UNPARSEABLE=" + (if $unparseable then "1" else "0" end), + "DRIFT=" + (if $drift then "1" else "0" end), + "PINNED_COUNT=" + (if $pinned == null then "" else ($pinned|tostring) end), + "SPREAD=" + (if $spread then "1" else "0" end) +``` + +Note: `$test_cmd` must always be passed via `--arg` by any caller — jq errors at compile time on an unbound variable, it does not default to `null`, so `$test_cmd // ""` only guards against an *empty string* value, never against a missing `--arg`. The smoke test's `jq_run` helper (Part A) passes `--arg test_cmd ""` for exactly this reason even though those fixtures don't care about the field's value. `test-count-rerun.sh` (Step 4 below) always passes the real value. + +- [ ] **Step 4: Write `hooks/lib/test-count-rerun.sh`** + +```bash +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/test-count-rerun.sh — test-count majority-vote rerun for +# /session-continuity:primer Step 4 (Refresh mode). See +# meta/superpowers/specs/2026-09-09-test-count-rerun-design.md for the +# full contract this implements (unchanged behavior from the prior +# hand-evaluated prose, just executable instead of hand-derived per +# invocation) and meta/superpowers/plans/2026-09-09-test-count-rerun.md +# for the implementation plan. +# +# Usage: test-count-rerun.sh <project-dir> <last-primer-commit> +# Prints KEY=value lines to stdout on success: TEST_CMD, RECORDED_COUNT, +# MODE (skip|no-command|no-count|run), RETRIES, OBSERVED, UNPARSEABLE, +# DRIFT, PINNED_COUNT, SPREAD. +# +# Operational failure (jq missing, test-count-rerun.jq missing or from a +# different CONTRACT_VERSION, <project-dir> not inside a git repository, +# PROJECT_CONTEXT.md unreadable) prints one diagnostic line to stderr and +# exits 1 with NO MODE= line on stdout at all. + +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JQ_FILTER="$SCRIPT_DIR/test-count-rerun.jq" +DIR="${1:-.}" +LAST_PRIMER_COMMIT="${2:-}" + +die() { # <message> + printf 'test-count-rerun.sh: %s\n' "$1" >&2 + exit 1 +} + +[[ -n "$LAST_PRIMER_COMMIT" ]] \ + || die "usage: test-count-rerun.sh <project-dir> <last-primer-commit>" +command -v jq >/dev/null 2>&1 \ + || die "jq is not installed, so the test-count rerun cannot be computed." +[[ -r "$JQ_FILTER" ]] \ + || die "test-count-rerun.jq is missing from $SCRIPT_DIR — the plugin cache is incomplete. Run \`/session-continuity:update\`." +grep -q '^# CONTRACT_VERSION=1$' "$JQ_FILTER" \ + || die "test-count-rerun.jq is from a different plugin version — run \`/session-continuity:update\`." +git -C "$DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1 \ + || die "$DIR is not inside a git repository." +CONTEXT_FILE="$DIR/.session-continuity/PROJECT_CONTEXT.md" +[[ -r "$CONTEXT_FILE" ]] \ + || die "$CONTEXT_FILE is not readable." + +# --- extract the Test-expectations summary line ---------------------------- +# Skip any HTML-comment lines (single- or multi-line <!-- ... -->) so a +# template's own exemplar comment is never mistaken for real content. +SUMMARY_LINE="$(awk ' + /^## Test expectations/ { insec=1; next } + insec && /^## / { exit } + insec { + if ($0 ~ /<!--/) incomment=1 + if (!incomment && $0 !~ /^[[:space:]]*$/) { print; exit } + if ($0 ~ /-->/) incomment=0 + } +' "$CONTEXT_FILE")" + +TEST_CMD="" +if [[ "$SUMMARY_LINE" =~ ^\`([^\`]+)\` ]]; then + TEST_CMD="${BASH_REMATCH[1]}" +fi + +RECORDED_COUNT="" +if [[ -n "$TEST_CMD" ]]; then + RECORDED_COUNT="$(printf '%s' "$SUMMARY_LINE" | grep -oE '[0-9]+ pass(ed)?' | head -1 | grep -oE '^[0-9]+' || true)" +fi + +# --- mode dispatch (labeling only -- the .jq filter's vote logic is the +# same regardless of which label sh assigns here) ---------------------- +if [[ -z "$TEST_CMD" ]]; then + MODE="no-command" +else + CHANGED_FILES="$(git -C "$DIR" diff "$LAST_PRIMER_COMMIT"..HEAD --name-only 2>/dev/null || true)" + SKIP=1 + while IFS= read -r f; do + [[ -z "$f" ]] && continue + case "$f" in .session-continuity/*) ;; *) SKIP=0 ;; esac + done <<<"$CHANGED_FILES" + if [[ "$SKIP" -eq 1 ]]; then + MODE="skip" + elif [[ -z "$RECORDED_COUNT" ]]; then + MODE="no-count" + else + MODE="run" + fi +fi + +# --- run the command 0-3 times per mode ------------------------------------- +# run_once's exit code is deliberately never inspected: "unparseable" is +# defined purely by the absence of a recognizable count in the output, +# not by a nonzero exit or a timeout. A `timeout`-killed run and a +# zero-exit run that simply printed no count both fall through to the +# same "no parseable count" outcome below -- there is exactly one code +# path for both, which is why the smoke test (B6) only needs to exercise +# unparseable *output*, not a separate timeout-specific fixture. +run_once() { # prints the parsed count, or nothing, on stdout + local out + out="$(cd "$DIR" && timeout 120 bash -c "$TEST_CMD" 2>&1)" + printf '%s' "$out" | grep -oE '[0-9]+ pass(ed)?' | head -1 | grep -oE '^[0-9]+' || true +} + +OBSERVED_JSON="[]" +case "$MODE" in + skip|no-command) + : # OBSERVED stays empty; the command never runs. + ;; + no-count) + v="$(run_once)" + OBSERVED_JSON="[$( [[ -n "$v" ]] && echo "$v" || echo null )]" + ;; + run) + v1="$(run_once)" + if [[ -n "$v1" && "$v1" == "$RECORDED_COUNT" ]]; then + OBSERVED_JSON="[$v1]" + else + v2="$(run_once)" + v3="$(run_once)" + to_json() { [[ -n "$1" ]] && echo "$1" || echo null; } + OBSERVED_JSON="[$(to_json "$v1"),$(to_json "$v2"),$(to_json "$v3")]" + fi + ;; +esac + +RECORDED_JSON="null" +[[ -n "$RECORDED_COUNT" ]] && RECORDED_JSON="$RECORDED_COUNT" + +ERRFILE="$(mktemp)" +RESULT="$( + jq -r -n \ + --arg test_cmd "$TEST_CMD" \ + --arg mode "$MODE" \ + --argjson recorded "$RECORDED_JSON" \ + --argjson observed "$OBSERVED_JSON" \ + -f "$JQ_FILTER" 2>"$ERRFILE" +)" +JQ_STATUS=$? +DETAIL="$(head -1 "$ERRFILE" 2>/dev/null)" +rm -f "$ERRFILE" + +if [[ "$JQ_STATUS" -ne 0 || -z "$RESULT" ]]; then + die "the vote filter failed: ${DETAIL:-jq exited $JQ_STATUS}" +fi + +printf '%s\n' "$RESULT" +``` + +```bash +chmod +x hooks/lib/test-count-rerun.sh +``` + +- [ ] **Step 5: Run the smoke test to verify all assertions pass** + +```bash +zsh meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh +``` + +Expected: `Result: 19 passed, 0 failed`. + +- [ ] **Step 6: Commit** + +```bash +git add hooks/lib/test-count-rerun.jq hooks/lib/test-count-rerun.sh meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh +git commit -m "feat: add test-count-rerun.sh/.jq, scripting primer Step 4's rerun vote" +``` + +--- + +### Task 2: `commands/primer.md` — call the script + +**Files:** +- Modify: `commands/primer.md` (Step 4 item 3, currently lines 285-300 as of `de381a8`) + +**Interfaces:** +- Consumes: `hooks/lib/test-count-rerun.sh` (Task 1), resolved via `CLAUDE_PLUGIN_ROOT` and `require_script`, exactly like `primer-detect.sh` already is in Step 1. + +- [ ] **Step 1: Replace item 3 in full** + +Using the Edit tool, replace this exact block (currently `commands/primer.md` lines 285-300, from `3. If the primer has a test-counts section...` through the line ending `...captured around this whole check.`): + +````markdown +3. If the primer has a test-counts section, decide whether to re-run it. + Do this as **one Bash call**, timed, tracking a `RETRIES` count (0 + if skipped or the first run matched, else the number of *extra* + runs actually executed beyond the first): + - **Skip the rerun** if `git diff <last-primer-commit>..HEAD --name-only` (the commit range since the primer was last touched) contains no file outside `.session-continuity/` — no source or test file changed, so the recorded count cannot have drifted. Reuse this diff if already computed elsewhere in this flow; don't recompute it just for this check. + - **Otherwise, run the test command(s) once.** If that single run's count matches the primer's recorded count, stop there — no drift on this axis, no further runs. + - **Only if that first run disagrees with the recorded count**, retry up to 2 more times (3 runs total) to rule out flakiness before reporting drift — a single sample can swing a pass/fail count and produce a false drift alarm. Pin to the count seen in ≥2 of the 3 runs. If that pinned count matches the primer's recorded count, the first run was the flake — no drift. If it differs, report drift with the pinned count. If all three runs disagree with each other, surface the spread (`saw 1162 / 1161 / 1162 across 3 runs — using 1162; suite is unstable`) instead of silently picking one. + + This keeps the common cases cheap: zero test runs when no relevant file changed, one run when relevant files changed but the count still holds, and the full 3-run majority vote only when there's an actual discrepancy to resolve. + + At the end of this Bash call (whichever branch above ran), call: + ```bash + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-test-count-rerun --duration="$_PERF_DURATION" --retries="$RETRIES" + ``` + using the same `_PERF_START`/`_PERF_END`/`_PERF_DURATION` pattern + shown in item 2 above, captured around this whole check. +```` + +with: + +````markdown +3. Run the shared test-count rerun script, timed: + + ```bash + _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) + source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" 1; then + RERUN_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" . "$LAST_PRIMER_COMMIT" 2>&1)" + RERUN_STATUS=$? + else + RERUN_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + RERUN_STATUS=1 + fi + _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") + RETRIES=$(printf '%s' "$RERUN_OUTPUT" | awk -F= '/^RETRIES=/{print $2}') + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-test-count-rerun --duration="$_PERF_DURATION" --retries="${RETRIES:-0}" + echo "$RERUN_OUTPUT" + echo "RERUN_STATUS=$RERUN_STATUS" + ``` + + **If `RERUN_STATUS` is nonzero, or `$RERUN_OUTPUT` has no `MODE=` line:** + report `$RERUN_OUTPUT` to the user and fall back to `TBD` for this + axis — never fabricate a drift verdict from a failed script. + + **Otherwise**, report per `MODE`: + - `skip` — no relevant file changed; say nothing (matches today's + silent skip). + - `no-command` — no test command recorded; nothing to check. + - `no-count`, `RETRIES=0`, `DRIFT=0` always — nothing recorded yet + to compare against; no report needed on this axis. + - `run` with `DRIFT=0` — the count held (whether on the first try or + after majority-vote confirmation); no report needed. + - `run` with `DRIFT=1` — report drift using `PINNED_COUNT` + (`"Test count drifted: recorded <RECORDED_COUNT>, now + <PINNED_COUNT> (confirmed over <RETRIES>+1 runs)."`). + - `run` with `SPREAD=1` — report instability using the comma-joined + `OBSERVED` values (`"Test suite is unstable: saw + <OBSERVED, /-joined> across 3 runs."`), not a drift verdict. + - `run` with `UNPARSEABLE=1` and no `PINNED_COUNT` — report + `"Test command produced no parseable count after <RETRIES>+1 + attempts."` +```` + +- [ ] **Step 2: Verify the old prose is gone** + +```bash +grep -c 'retry up to 2 more times\|Pin to the count seen in' commands/primer.md +``` + +Expected: `0` — the majority-vote mechanics now live only in `test-count-rerun.jq`, referenced by its output fields everywhere else. + +- [ ] **Step 3: Commit** + +```bash +git add commands/primer.md +git commit -m "refactor: primer.md Step 4 item 3 dispatches via test-count-rerun.sh" +``` + +--- + +### Task 3: Doc pointers, regression pass, changelog + +**Files:** +- Modify: `meta/superpowers/specs/2026-09-02-determinism-program-design.md` +- Modify: `CHANGELOG.md` +- Modify: `.claude-plugin/plugin.json` + +- [ ] **Step 1: Update the design doc's Phase 6 entry** + +Using the Edit tool, replace this exact block in `meta/superpowers/specs/2026-09-02-determinism-program-design.md`: + +```markdown +**Phase 6 `#43` — `primer` detect, migrate, init, drift.** Decomposed into +five sub-projects (see `meta/superpowers/specs/2026-09-08-primer-detect-design.md`'s +Context section for the full breakdown and why): **sub-project A shipped** +— Step 1's mode detection plus all three migration triggers, previously +hand-evaluated nested conditionals with an easy-to-miss sequencing rule, +now `hooks/lib/primer-detect.sh`/`.jq`. Plan: +`meta/superpowers/plans/2026-09-08-primer-detect.md`. Still pending: +sub-project B (Step 4's test-count majority-vote rerun — the same +compare-a-claimed-value-against-an-actual-one class Phase 7 is being +built to gate against), C (Step 3c/3d's `git mv`/`git rm` migration +mechanics themselves — sub-project A only scripted *whether* they run, +not *what* they do), D (Step 2's placeholder-derivation gather-and-regex), +E (Step 3/3b's section-bucketing judgment, lowest priority — near-zero +remaining audience, most judgment-heavy of the five). +``` + +with: + +```markdown +**Phase 6 `#43` — `primer` detect, migrate, init, drift.** Decomposed into +five sub-projects (see `meta/superpowers/specs/2026-09-08-primer-detect-design.md`'s +Context section for the full breakdown and why): **sub-project A shipped** +— Step 1's mode detection plus all three migration triggers, now +`hooks/lib/primer-detect.sh`/`.jq`. Plan: +`meta/superpowers/plans/2026-09-08-primer-detect.md`. **Sub-project B +shipped** — Step 4's test-count majority-vote rerun (the +compare-a-claimed-value-against-an-actual-one class Phase 7 is being +built to gate against), now `hooks/lib/test-count-rerun.sh`/`.jq`. Spec: +`meta/superpowers/specs/2026-09-09-test-count-rerun-design.md`. Plan: +`meta/superpowers/plans/2026-09-09-test-count-rerun.md`. Still pending: +C (Step 3c/3d's `git mv`/`git rm` migration mechanics themselves — +sub-project A only scripted *whether* they run, not *what* they do), D +(Step 2's placeholder-derivation gather-and-regex), E (Step 3/3b's +section-bucketing judgment, lowest priority — near-zero remaining +audience, most judgment-heavy of the five). +``` + +- [ ] **Step 2: Full regression pass** + +```bash +for f in \ + meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh \ + meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh \ + meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh \ + meta/superpowers/validation/2026-08-17-perf-log-smoke.zsh \ + meta/superpowers/validation/2026-09-03-primer-status-smoke.zsh \ + meta/superpowers/validation/2026-08-12-session-start-smoke.zsh \ + meta/superpowers/validation/2026-09-01-require-script-smoke.zsh \ + meta/superpowers/validation/2026-09-07-backlog-issues-smoke.zsh \ + meta/superpowers/validation/2026-09-01-agent-active-smoke.zsh \ + meta/superpowers/validation/2026-09-02-resolve-transcript-smoke.zsh \ + meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh \ + meta/superpowers/validation/2026-09-02-candidate-render-smoke.zsh \ + meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh +do + echo "--- $f ---" + zsh "$f" || echo "FAILED: $f" +done +``` + +Expected: every runner ends `0 failed`. + +- [ ] **Step 3: Add a CHANGELOG entry** + +Add a new section at the top of `CHANGELOG.md`, directly under the `# Changelog` header and its description line, above the current top entry: + +```markdown +## [0.33.0] — 2026-09-09 + +### Changed +- **`/session-continuity:primer`'s Step 4 test-count rerun is now scripted.** New `hooks/lib/test-count-rerun.sh`/`.jq` replace ~8 lines of hand-evaluated majority-vote prose (skip-check, run-once-then-compare, retry-to-3-on-mismatch, pin-to-majority, spread-on-3-way-disagreement) with one script call. The `.jq` filter's vote algorithm is mode-agnostic — the `skip`/`no-command`/`no-count` cases' "always empty" outputs fall out of the same generic majority computation applied to a 0- or 1-element observation array, with no per-mode special casing. Unparseable test runs (timeout, crash, no recognizable count) are now handled explicitly: they consume a retry slot but cast no vote, so a 2-of-2 parseable majority still pins even when the third run was unparseable, and a genuine 2-way disagreement with one unparseable run reports spread rather than a false no-drift. Determinism Phase 6 (#43) sub-project B; sub-projects C-E remain pending. +``` + +- [ ] **Step 4: Bump the plugin version** + +Using the Edit tool, update `.claude-plugin/plugin.json`'s `"version"` field from `"0.32.0"` to `"0.33.0"`. + +- [ ] **Step 5: Commit** + +```bash +git add meta/superpowers/specs/2026-09-02-determinism-program-design.md CHANGELOG.md .claude-plugin/plugin.json +git commit -m "docs: Phase 6 sub-project B doc pointers, changelog, and version bump" +``` diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index d88083a..63c78bb 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -207,17 +207,19 @@ intersection cardinality is a task models get wrong silently. **Phase 6 `#43` — `primer` detect, migrate, init, drift.** Decomposed into five sub-projects (see `meta/superpowers/specs/2026-09-08-primer-detect-design.md`'s Context section for the full breakdown and why): **sub-project A shipped** -— Step 1's mode detection plus all three migration triggers, previously -hand-evaluated nested conditionals with an easy-to-miss sequencing rule, -now `hooks/lib/primer-detect.sh`/`.jq`. Plan: -`meta/superpowers/plans/2026-09-08-primer-detect.md`. Still pending: -sub-project B (Step 4's test-count majority-vote rerun — the same +— Step 1's mode detection plus all three migration triggers, now +`hooks/lib/primer-detect.sh`/`.jq`. Plan: +`meta/superpowers/plans/2026-09-08-primer-detect.md`. **Sub-project B +shipped** — Step 4's test-count majority-vote rerun (the compare-a-claimed-value-against-an-actual-one class Phase 7 is being -built to gate against), C (Step 3c/3d's `git mv`/`git rm` migration -mechanics themselves — sub-project A only scripted *whether* they run, -not *what* they do), D (Step 2's placeholder-derivation gather-and-regex), -E (Step 3/3b's section-bucketing judgment, lowest priority — near-zero -remaining audience, most judgment-heavy of the five). +built to gate against), now `hooks/lib/test-count-rerun.sh`/`.jq`. Spec: +`meta/superpowers/specs/2026-09-09-test-count-rerun-design.md`. Plan: +`meta/superpowers/plans/2026-09-09-test-count-rerun.md`. Still pending: +C (Step 3c/3d's `git mv`/`git rm` migration mechanics themselves — +sub-project A only scripted *whether* they run, not *what* they do), D +(Step 2's placeholder-derivation gather-and-regex), E (Step 3/3b's +section-bucketing judgment, lowest priority — near-zero remaining +audience, most judgment-heavy of the five). **Phase 7 `#44` — the gate that keeps it true.** A commit-time content gate on staged `commands/*.md` that blocks prompt text instructing a model to count, diff --git a/meta/superpowers/specs/2026-09-09-test-count-rerun-design.md b/meta/superpowers/specs/2026-09-09-test-count-rerun-design.md new file mode 100644 index 0000000..701a038 --- /dev/null +++ b/meta/superpowers/specs/2026-09-09-test-count-rerun-design.md @@ -0,0 +1,198 @@ +# Design — `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B) + +**Issue:** #43 (Determinism Phase 6 — `primer` detect, migrate, init, drift) + +## Context + +`meta/superpowers/specs/2026-09-08-primer-detect-design.md` scoped Phase 6 +into five sub-projects and shipped only sub-project A (Step 1's +detect/dispatch logic, PR #52). This spec covers **sub-project B only**: +`commands/primer.md` Step 4 item 3 (lines 285-292 as of `de381a8`) — the +test-count majority-vote rerun that runs during Refresh mode. + +This repo's own `.session-continuity/PROJECT_CONTEXT.md` records "No +automated test suite," so this sub-project cannot be dogfooded against a +real run here — same constraint sub-project A had for `git mv`-class +migrations, solved the same way: synthetic fixtures over real scratch +repos, not live dogfooding. + +## Problem + +Step 4 item 3 today is ~8 lines of prose the model re-executes by hand +every Refresh-mode invocation: decide whether a rerun is even warranted +(via a git-diff skip check), run the recorded test command once, and — +only on disagreement with the recorded count — retry up to 2 more times, +pin to a ≥2-of-3 majority, and report either drift or an unstable-suite +spread. This is the same class of hand-evaluated conditional logic Phases +4-6A already found unreliable when left to per-invocation prose +re-derivation, and it is Phase 6's other highest-frequency piece (every +drift-detected Refresh-mode call, per the original phase table). + +## Recorded-count format (existing, unchanged) + +`commands/primer.md` Step 2 (Init mode) already seeds +`PROJECT_CONTEXT.md`'s `{{TEST_COMMAND_SUMMARY}}` placeholder as +`` `<TEST_CMD>` — N pass / M fail `` when the init test run had exit 0 and +a parseable count, else the bare command string, else `TBD` — never an +invented count (line 114). Step 4's rerun reads this same line back, but +**only `N` (pass count) round-trips as `RECORDED_COUNT`/`OBSERVED`** — `M` +(fail count) is parsed for display purposes only and never compared. +This means a newly-failing test that doesn't change `N` (e.g. a new test +added and immediately failing, holding the pass count steady while `M` +rises from 0) produces no drift signal on this axis — same blind spot +the current hand-evaluated prose already has, since it only ever +mentions "the primer's recorded count," singular. Not fixed here; +flagged as a real limitation inherited, not introduced. + +## Architecture + +``` +test-count-rerun.sh (I/O) test-count-rerun.jq (pure decision) + - read PROJECT_CONTEXT.md's - given {recorded, mode, observed:[...]} + TEST_COMMAND_SUMMARY line - mode=="skip" -> RETRIES=0, DRIFT=0 + - parse <TEST_CMD> + recorded N - mode=="run": majority-vote / + - git diff <last-primer-commit>..HEAD drift / spread over observed[] + --name-only -> skip decision + - if not skipped: run <TEST_CMD>, + parse observed count, once + - if observed[0] != recorded: run + <TEST_CMD> 2 more times, parse each + - emit facts to stdout +``` + +`test-count-rerun.sh` never decides drift/majority itself — it only +decides *whether to run* (the skip check) and *how many times* (stop +after 1 if it matches, else run to 3), because that decision requires an +actual test-run count it doesn't have until it runs. It hands the full +`observed` array to the `.jq` filter for the pure vote/drift/spread +logic, which is fixture-testable with synthetic JSON and needs no git or +subprocess access. This mirrors `token-overlap.sh`/`.jq`'s split (I/O +shim computes once, pure filter decides), not `primer-detect.sh`/`.jq`'s +(which reads only static facts) — here the I/O side is stateful across +up to 3 runs, so the shim itself must implement the "stop early on +match" short-circuit; only the *voting* over whatever it collected moves +to `.jq`. + +**Count parsing** duplicates (does not import) Step 2's regex family — +`N pass`, `N passed`, `test result: ok. N passed`, else unparseable. Step +2's version lives inline in `commands/primer.md` prose, not in a script; +sub-project D (Step 2's placeholder derivation) is the one that would +extract it to a shared script, and is explicitly out of scope here. This +sub-project accepts the short-term duplication rather than reaching into +D's scope. + +## Output contract + +`test-count-rerun.sh <project-dir> <last-primer-commit>` prints, always +to stdout on success: + +``` +TEST_CMD=<string, empty only in MODE=no-command> +RECORDED_COUNT=<int, or empty if PROJECT_CONTEXT.md had no parseable count> +MODE=skip|run|no-command|no-count +RETRIES=<int, 0-2> +OBSERVED=<comma-separated, one entry per run executed in order, an + entry is empty if that run's output had no parseable count> +UNPARSEABLE=0|1 <- 1 iff any OBSERVED entry is empty +DRIFT=0|1 +PINNED_COUNT=<int, empty unless some value has >=2 parseable votes> +SPREAD=0|1 <- 1 iff PINNED_COUNT is empty AND >=2 distinct parseable + values were observed (a real disagreement, not just missing data) +``` + +`DRIFT` and `SPREAD` are mutually exclusive: `DRIFT=1` requires a +non-empty `PINNED_COUNT`; `SPREAD=1` only fires when no value pinned. +Vote counting (`PINNED_COUNT`, `SPREAD`) considers only the parseable +entries in `OBSERVED` — an unparseable run still counts against the +3-run budget (`RETRIES`) but casts no vote. Two parseable agreeing +observations pin a majority even if the third run was unparseable +(2-of-2 parseable, not strictly 2-of-3 raw); if the two parseable runs +instead disagree, no majority exists — same as a 3-way disagreement, +so `SPREAD=1`. + +`MODE=skip`: the git-diff check found no file outside `.session-continuity/` +changed since the last primer touch — `RETRIES=0`, `OBSERVED=` empty, +`UNPARSEABLE=0`, `DRIFT=0`, `SPREAD=0`. + +`MODE=no-command`: `PROJECT_CONTEXT.md`'s `TEST_COMMAND_SUMMARY` line has +no `<TEST_CMD>` (bare `TBD`, or the line is missing/unparseable) — nothing +to rerun. `RETRIES=0`, `DRIFT=0`, `SPREAD=0`. + +`MODE=no-count`: `TEST_CMD` exists but `RECORDED_COUNT` doesn't (the +seeded line fell back to the bare command string) — there is nothing to +diff against. The command still runs once so the caller can seed a count +going forward, but `DRIFT` is always `0` and `SPREAD` always `0` in this +mode — you cannot drift from, or disagree against, a value that was +never recorded. + +`MODE=run`: the normal path. Runs 1-3 times per the majority-vote rule +already in the current prose (unchanged behavior, now scripted): first +run matching `RECORDED_COUNT` stops at `RETRIES=0`; a mismatch triggers +2 more runs. Outcomes, by how many of up to 3 runs are parseable and +what they show: +- **A value gets ≥2 parseable votes** — `PINNED_COUNT` = that value, + `DRIFT=1` iff it differs from `RECORDED_COUNT`, `SPREAD=0`. This is + the normal case, and also covers 2-of-2 when the third run was + unparseable. +- **≥2 distinct parseable values, none reaching a majority** (all 3 + disagree, or 2 disagree and the third was unparseable) — `SPREAD=1`, + `PINNED_COUNT` empty, `DRIFT=0`. The caller reports the raw spread + from `OBSERVED` (matching the current prose's `"saw 1162 / 1161 / + 1162 across 3 runs"` phrasing) instead of a drift verdict. +- **Fewer than 2 parseable observations total** (0 or 1, the rest + unparseable/timed out) — `PINNED_COUNT` empty, `DRIFT=0`, `SPREAD=0` + (there's no disagreement to report, just missing data). + `UNPARSEABLE=1` distinguishes this from the ordinary + no-drift-detected case; the caller surfaces "test command produced + no parseable count after N attempts" rather than silently reporting + no drift. + +## Error handling + +Operational failure (jq missing, `test-count-rerun.jq` missing or +`CONTRACT_VERSION`-mismatched, `PROJECT_CONTEXT.md` unreadable) prints +one diagnostic line to stderr and exits nonzero with no `MODE=` line at +all. Unlike `primer-detect.sh`, a wrong guess here is not destructive +(no `git mv`/`git rm` downstream) — but `commands/primer.md` still must +not fabricate a drift verdict on script failure; it falls back to +`TBD`/manual reporting, same as any other derived-field failure per this +file's "never invent a count" rule (line 371). + +## Testing + +Fixture-driven, split across both layers: + +- `.jq` filter: synthetic JSON fixtures (no git, no subprocess) covering + the vote/drift/spread matrix — match-on-first-run, drift confirmed by + majority, spread (3-way disagreement), spread from 2-parseable-disagree + plus 1 unparseable, 2-of-2-parseable-agree majority with the third + unparseable, all-3-unparseable (`UNPARSEABLE=1`, `SPREAD=0`, + `PINNED_COUNT` empty), and the `skip`/`no-command`/`no-count` + short-circuit modes. +- `.sh` shim: scratch git repos with a fake `TEST_CMD` (a tiny script + that echoes a controlled count, invocation-counted via a side file so + the fixture can assert exactly how many times it ran) — covering the + skip-check's git-diff logic, the stop-after-1-on-match short circuit, + and the timeout/nonzero/unparseable-output edge case (including all 3 + runs unparseable, to confirm the shim still emits a well-formed + `OBSERVED=` with 3 empty entries rather than erroring out). + +Mirrors `meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh`'s +format. New runner: +`meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh`. + +## Rollout + +`commands/primer.md` Step 4 item 3's prose is replaced with: run +`test-count-rerun.sh`, then report per the `MODE`/`DRIFT`/`SPREAD` +contract above (the reporting sentence itself — "drift with the pinned +count" / "suite is unstable" / etc. — stays prose, since it's the kind of +short user-facing formatting Phase 4/5 already left as prose elsewhere). +Version bump + CHANGELOG entry, following the Phase 4/5/6A precedent. + +## Out of scope + +Sub-projects C (Step 3c/3d migration mechanics), D (Step 2's placeholder +derivation — including the shared count-parsing regex this sub-project +duplicates), and E (Step 3/3b section-bucketing judgment) are each their +own future spec/plan cycle. diff --git a/meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh b/meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh new file mode 100755 index 0000000..48202f0 --- /dev/null +++ b/meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh @@ -0,0 +1,235 @@ +#!/usr/bin/env zsh +# test-count-rerun.sh/.jq smoke test. Two layers: +# Part A: .jq fixtures via synthetic JSON (no git, no subprocess) -- the +# vote/drift/spread/unparseable matrix. +# Part B: .sh integration fixtures via scratch git repos with a fake, +# invocation-counted TEST_CMD -- the skip check, the +# extraction format, and the match-then-retry run count. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +jq_filter="$lib/test-count-rerun.jq" +tool="$lib/test-count-rerun.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +# --------------------------------------------------------------------------- +# Part A: .jq fixtures +# --------------------------------------------------------------------------- + +jq_run() { # <mode> <recorded-json> <observed-json> -> full KEY=value output + # --arg test_cmd "" is required even though these fixtures don't care + # about TEST_CMD's value: jq errors at compile time on an unbound $var, + # it does not treat a never-passed --arg as null, so the filter's own + # "$test_cmd // \"\"" guard never gets a chance to run without this. + jq -r -n --arg mode "$1" --argjson recorded "$2" --argjson observed "$3" --arg test_cmd "" -f "$jq_filter" +} +jq_field() { # <output> <KEY> -> value + print -r -- "$1" | awk -F= -v k="$2" '$1==k{print substr($0, length(k)+2)}' +} + +# A1: skip mode, empty observed -> all zeros +out="$(jq_run skip null '[]')" +[[ "$(jq_field "$out" MODE)" == "skip" && "$(jq_field "$out" RETRIES)" == "0" \ + && "$(jq_field "$out" DRIFT)" == "0" && "$(jq_field "$out" SPREAD)" == "0" \ + && "$(jq_field "$out" UNPARSEABLE)" == "0" ]] \ + && ok "A1: skip -> all zeros" || bad "A1: got '$out'" + +# A2: match on first run -> no drift, no pin (only 1 observation) +out="$(jq_run run 1162 '[1162]')" +[[ "$(jq_field "$out" DRIFT)" == "0" && "$(jq_field "$out" PINNED_COUNT)" == "" \ + && "$(jq_field "$out" RETRIES)" == "0" ]] \ + && ok "A2: first-run match -> no drift, unpinned" || bad "A2: got '$out'" + +# A3: 2-of-3 majority confirms drift +out="$(jq_run run 1162 '[1161,1161,1162]')" +[[ "$(jq_field "$out" PINNED_COUNT)" == "1161" && "$(jq_field "$out" DRIFT)" == "1" \ + && "$(jq_field "$out" SPREAD)" == "0" && "$(jq_field "$out" RETRIES)" == "2" ]] \ + && ok "A3: 2-of-3 majority -> drift confirmed" || bad "A3: got '$out'" + +# A4: 2-of-3 majority matches recorded -> first run was the flake, no drift +out="$(jq_run run 1162 '[1161,1162,1162]')" +[[ "$(jq_field "$out" PINNED_COUNT)" == "1162" && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A4: 2-of-3 majority matches recorded -> no drift" || bad "A4: got '$out'" + +# A5: all 3 disagree -> spread, no pin, no drift +out="$(jq_run run 1162 '[1160,1161,1162]')" +[[ "$(jq_field "$out" SPREAD)" == "1" && "$(jq_field "$out" PINNED_COUNT)" == "" \ + && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A5: 3-way disagreement -> spread" || bad "A5: got '$out'" + +# A6: 2 parseable disagree + 1 unparseable -> spread (not a false no-drift) +out="$(jq_run run 1162 '[1161,null,1162]')" +[[ "$(jq_field "$out" SPREAD)" == "1" && "$(jq_field "$out" UNPARSEABLE)" == "1" \ + && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A6: 2 disagree + 1 unparseable -> spread" || bad "A6: got '$out'" + +# A7: 2-of-2 parseable agree, 3rd unparseable -> majority still pins +out="$(jq_run run 1162 '[1161,null,1161]')" +[[ "$(jq_field "$out" PINNED_COUNT)" == "1161" && "$(jq_field "$out" DRIFT)" == "1" \ + && "$(jq_field "$out" SPREAD)" == "0" && "$(jq_field "$out" UNPARSEABLE)" == "1" ]] \ + && ok "A7: 2-of-2 parseable agree (3rd unparseable) -> pinned" || bad "A7: got '$out'" + +# A8: all 3 unparseable -> no pin, no spread, UNPARSEABLE=1 +out="$(jq_run run 1162 '[null,null,null]')" +[[ "$(jq_field "$out" UNPARSEABLE)" == "1" && "$(jq_field "$out" SPREAD)" == "0" \ + && "$(jq_field "$out" PINNED_COUNT)" == "" && "$(jq_field "$out" DRIFT)" == "0" ]] \ + && ok "A8: all 3 unparseable -> no pin, no spread" || bad "A8: got '$out'" + +# A9: no-count mode, single run, no recorded value -> never drifts +out="$(jq_run no-count null '[1162]')" +[[ "$(jq_field "$out" DRIFT)" == "0" && "$(jq_field "$out" SPREAD)" == "0" \ + && "$(jq_field "$out" RECORDED_COUNT)" == "" ]] \ + && ok "A9: no-count -> never drifts, recorded stays empty" || bad "A9: got '$out'" + +# A10: no-command mode, no observations +out="$(jq_run no-command null '[]')" +[[ "$(jq_field "$out" MODE)" == "no-command" && "$(jq_field "$out" RETRIES)" == "0" ]] \ + && ok "A10: no-command -> zero retries" || bad "A10: got '$out'" + +# --------------------------------------------------------------------------- +# Part B: .sh integration fixtures +# --------------------------------------------------------------------------- + +# mk_repo <dir> <summary-line> -> scratch repo with PROJECT_CONTEXT.md's Test +# expectations section set to <summary-line>, committed, primer touched at +# HEAD (so <last-primer-commit> == HEAD unless the caller commits more after). +mk_repo() { + local dir="$1" summary="$2" + rm -rf "$dir"; mkdir -p "$dir/.session-continuity" + git -C "$dir" init -q + git -C "$dir" config user.email test@example.com + git -C "$dir" config user.name Test + print -r -- "# Context + +## Test expectations — these must stay green + +$summary + +## End-to-end check +" > "$dir/.session-continuity/PROJECT_CONTEXT.md" + print -r -- "# Primer" > "$dir/.session-continuity/SESSION_PRIMER.md" + git -C "$dir" add -A + git -C "$dir" commit -qm init +} + +# fake_cmd <dir> <counter-file> <sequence...> -> writes a TEST_CMD script at +# <dir>/fake-test.sh that pops one value off <sequence> per invocation +# (appending its own PID-independent invocation count to <counter-file>) and +# echoes "<value> pass" (or nothing, for a deliberately unparseable run, +# encoded as the literal token "UNPARSEABLE"). +fake_cmd() { + local dir="$1" counter="$2"; shift 2 + : > "$counter" + print -r -- '#!/usr/bin/env bash' > "$dir/fake-test.sh" + print -r -- "seq=($*)" >> "$dir/fake-test.sh" + cat >> "$dir/fake-test.sh" <<'EOF' +n=$(wc -l < "$COUNTER_FILE") +val="${seq[$n]}" +echo "run" >> "$COUNTER_FILE" +if [[ "$val" == "UNPARSEABLE" ]]; then + echo "no count here" +else + echo "$val pass" +fi +EOF + chmod +x "$dir/fake-test.sh" +} + +last_commit() { git -C "$1" log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md; } + +# B1: skip mode -- only .session-continuity/ files changed since last primer touch +d="$work/b1"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +lc="$(last_commit "$d")" +print -r -- x >> "$d/.session-continuity/LEARNINGS.md" +git -C "$d" add -A; git -C "$d" commit -qm "docs only" +out="$(cd "$d" && bash "$tool" "$d" "$lc" 2>&1)" +[[ "$out" == *"MODE=skip"* ]] && ok "B1: docs-only change -> skip" || bad "B1: got '$out'" + +# B2: no-command mode -- freeform prose, no backtick-quoted command +d="$work/b2"; mk_repo "$d" 'No automated test suite. Validation is manual.' +lc="$(last_commit "$d")" +out="$(cd "$d" && bash "$tool" "$d" "$lc" 2>&1)" +[[ "$(jq_field "$out" MODE)" == "no-command" && "$(jq_field "$out" TEST_CMD)" == "" ]] \ + && ok "B2: freeform prose -> no-command, empty TEST_CMD" || bad "B2: got '$out'" + +# B3: no-count mode -- backtick command present, no parseable count +d="$work/b3"; mk_repo "$d" '`./fake-test.sh`' +lc="$(last_commit "$d")" +touch "$d/some-file" +git -C "$d" add -A; git -C "$d" commit -qm "code change" +fake_cmd "$d" "$d/counter" "3" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$lc" 2>&1)" +[[ "$(jq_field "$out" MODE)" == "no-count" ]] && ok "B3: bare command, no count -> no-count" || bad "B3: got '$out'" + +# B4: run mode, first-run match -> exactly 1 invocation, no drift +d="$work/b4"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +lc="$(last_commit "$d")" +touch "$d/some-file" +git -C "$d" add -A; git -C "$d" commit -qm "code change" +fake_cmd "$d" "$d/counter" "3" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$lc" 2>&1)" +invocations="$(wc -l < "$d/counter" | tr -d ' ')" +[[ "$(jq_field "$out" MODE)" == "run" && "$(jq_field "$out" DRIFT)" == "0" && "$invocations" == "1" ]] \ + && ok "B4: first-run match -> 1 invocation, no drift" || bad "B4: got '$out' (invocations=$invocations)" + +# B5: run mode, first-run mismatch -> retries to 3, drift confirmed +d="$work/b5"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +lc="$(last_commit "$d")" +touch "$d/some-file" +git -C "$d" add -A; git -C "$d" commit -qm "code change" +fake_cmd "$d" "$d/counter" "4" "4" "4" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$lc" 2>&1)" +invocations="$(wc -l < "$d/counter" | tr -d ' ')" +[[ "$(jq_field "$out" DRIFT)" == "1" && "$(jq_field "$out" PINNED_COUNT)" == "4" && "$invocations" == "3" ]] \ + && ok "B5: mismatch -> 3 invocations, drift confirmed" || bad "B5: got '$out' (invocations=$invocations)" + +# B6: run mode, all 3 runs unparseable -> well-formed OBSERVED, no crash +d="$work/b6"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +lc="$(last_commit "$d")" +touch "$d/some-file" +git -C "$d" add -A; git -C "$d" commit -qm "code change" +fake_cmd "$d" "$d/counter" "UNPARSEABLE" "UNPARSEABLE" "UNPARSEABLE" +out="$(cd "$d" && COUNTER_FILE="$d/counter" bash "$tool" "$d" "$lc" 2>&1)" +[[ "$out" == *"UNPARSEABLE=1"* && "$out" == *"OBSERVED=,,"* ]] \ + && ok "B6: all 3 unparseable -> well-formed OBSERVED, UNPARSEABLE=1" || bad "B6: got '$out'" + +# --------------------------------------------------------------------------- +# Operational failure cases +# --------------------------------------------------------------------------- + +# B7: missing .jq filter +d="$work/b7"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +badlib="$work/badlib"; mkdir -p "$badlib"; cp "$tool" "$badlib/" +out="$(bash "$badlib/test-count-rerun.sh" "$d" "$(last_commit "$d")" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"MODE="* ]] \ + && ok "B7: missing filter -> nonzero exit, no MODE= line" || bad "B7: rc=$rc out='$out'" + +# B8: wrong CONTRACT_VERSION +d="$work/b8"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +wronglib="$work/wronglib"; mkdir -p "$wronglib"; cp "$tool" "$wronglib/" +sed 's/CONTRACT_VERSION=1/CONTRACT_VERSION=99/' "$jq_filter" > "$wronglib/test-count-rerun.jq" +out="$(bash "$wronglib/test-count-rerun.sh" "$d" "$(last_commit "$d")" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"MODE="* ]] \ + && ok "B8: wrong CONTRACT_VERSION -> nonzero exit, no MODE= line" || bad "B8: rc=$rc out='$out'" + +# B9: jq absent from PATH +d="$work/b9"; mk_repo "$d" '`./fake-test.sh` — 3 pass / 0 fail' +nojq="$work/nojq"; mkdir -p "$nojq/bin" +for b in bash git awk grep sed head cat mktemp dirname timeout wc tr; do + p="$(command -v "$b")"; [[ -n "$p" ]] && ln -sf "$p" "$nojq/bin/$b" +done +out="$(PATH="$nojq/bin" bash "$tool" "$d" "$(last_commit "$d")" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"MODE="* ]] \ + && ok "B9: jq absent from PATH -> nonzero exit, no MODE= line" || bad "B9: rc=$rc out='$out'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) From ac36beea63e61e3d78d87e1fe99a5fb62ccbf508 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Wed, 9 Sep 2026 11:16:12 -0700 Subject: [PATCH 15/20] Determinism Phase 6 sub-project D: primer-init-derive.sh/.jq (#58) * docs: spec + plan for Phase 6 sub-project D (primer-init-derive) * feat: add primer-init-derive.sh/.jq, scripting primer Step 2's placeholder derivation * refactor: primer.md Step 2 item 6 dispatches via primer-init-derive.sh * docs: Phase 6 sub-project D doc pointers, changelog, and version bump --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 16 + commands/primer.md | 29 +- hooks/lib/primer-init-derive.jq | 40 + hooks/lib/primer-init-derive.sh | 89 +++ .../plans/2026-09-09-primer-init-derive.md | 739 ++++++++++++++++++ .../2026-09-02-determinism-program-design.md | 14 +- .../2026-09-09-primer-init-derive-design.md | 254 ++++++ .../2026-09-09-primer-init-derive-smoke.zsh | 202 +++++ 9 files changed, 1374 insertions(+), 11 deletions(-) create mode 100644 hooks/lib/primer-init-derive.jq create mode 100755 hooks/lib/primer-init-derive.sh create mode 100644 meta/superpowers/plans/2026-09-09-primer-init-derive.md create mode 100644 meta/superpowers/specs/2026-09-09-primer-init-derive-design.md create mode 100755 meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 54eebd1..635cd72 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session-continuity", - "version": "0.33.0", + "version": "0.34.0", "description": "Cross-session memory for Claude Code projects via four in-repo docs: SESSION_PRIMER.md (current state), PROJECT_CONTEXT.md (stable repo context), ROADMAP.md (strategic direction), and LEARNINGS.md (hard-won bugs), plus GitHub Issues labeled backlog for the work queue.", "author": { "name": "Tal Golan" diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a11a86..12fea48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.34.0] — 2026-09-09 + +### Changed +- **`/session-continuity:primer`'s Step 2 placeholder derivation is now + scripted.** New `hooks/lib/primer-init-derive.sh`/`.jq` replace four + hand-evaluated derivations (`{{PROJECT_NAME}}`'s manifest-priority pick, + `{{LATEST_COMMIT_HASH_N}}`/`{{LATEST_COMMIT_SUBJECT_N}}`'s git-log split, + `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}`'s passthrough, + `{{TEST_COMMAND_SUMMARY}}`'s pass/fail-count regex) with one script call. + `{{MODULES_TABLE}}`'s docblock parsing, `{{REPO_LAYOUT_SUMMARY}}`'s + inferred sentence, and `{{WORKFLOW_CONVENTIONS}}`'s draft stay prose — + each depends on arbitrary per-project convention, not a fixed format, the + same reasoning that already excluded the latter two from this program. + Determinism Phase 6 (#43) sub-project D; sub-projects C and E remain + pending. + ## [0.33.0] — 2026-09-09 ### Changed diff --git a/commands/primer.md b/commands/primer.md index 5ac4573..537d2c2 100644 --- a/commands/primer.md +++ b/commands/primer.md @@ -105,13 +105,32 @@ trigger Step 4 or Step 5 a second time. _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-2-init-derive-placeholders --duration="$_PERF_DURATION" + export TEST_CMD TEST_OUTPUT + source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-init-derive.sh" 1; then + DERIVE_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-init-derive.sh" . 2>&1)" + DERIVE_STATUS=$? + else + DERIVE_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + DERIVE_STATUS=1 + fi + echo "$DERIVE_OUTPUT" + echo "DERIVE_STATUS=$DERIVE_STATUS" ``` - Derive from that output: - - `{{PROJECT_NAME}}` — from `package.json` `name`, `Cargo.toml` `name`, `pyproject.toml` `name`, or the current directory basename. - - `{{LATEST_COMMIT_HASH_N}}` / `{{LATEST_COMMIT_SUBJECT_N}}` — from the `git log --oneline -5` output above. - - `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}` — from the `pwd` output above. - - `{{TEST_COMMAND_SUMMARY}}` — if `TEST_RUN_EXIT=0` and the captured output contains a recognizable count (`N pass`, `N passed`, `test result: ok. N passed`, etc.), seed this as "`<TEST_CMD>` — N pass / M fail" from that single run. If `TEST_CMD` was empty, the run timed out (`TEST_RUN_EXIT=124`), or the output has no parseable count, fall back to the bare `scripts.test` string (or `TBD`) — never invent a count. + **If `DERIVE_STATUS` is nonzero, or `$DERIVE_OUTPUT` has no + `PROJECT_NAME=` line:** report `$DERIVE_OUTPUT` to the user and ask for + `{{PROJECT_NAME}}`, the commit placeholders, and `{{TEST_COMMAND_SUMMARY}}` + manually in Step 7 below — never fabricate these from a failed script. + + **Otherwise**, fill directly from `$DERIVE_OUTPUT`'s fields: + - `{{PROJECT_NAME}}` — `PROJECT_NAME`. + - `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}` — `WORKING_DIRECTORY_ABSOLUTE_PATH`. + - `{{LATEST_COMMIT_HASH_N}}` / `{{LATEST_COMMIT_SUBJECT_N}}` — for each + `N` from 1 to `COMMIT_COUNT`, `LATEST_COMMIT_HASH_N` / + `LATEST_COMMIT_SUBJECT_N`. If `COMMIT_COUNT` is below 5, leave the + template's remaining `N` slots as `TBD` rather than writing empty pairs. + - `{{TEST_COMMAND_SUMMARY}}` — `TEST_COMMAND_SUMMARY`, verbatim. - `{{REPO_LAYOUT_SUMMARY}}` — from the `find` output above, plus a one-line description Claude infers from the file extensions present. - `{{MODULES_TABLE}}` — if the `@module` grep above found matches, build one table row per file: Component = file path, Purpose = the `@module` value (plus the docblock's one-line description if present), Notes = the adjacent `Exports:` line if present. If it found nothing, leave `TBD` as before — don't invent structure that isn't there. - `{{WORKFLOW_CONVENTIONS}} (draft)` — if `CLAUDE.md` exists (cat output above), draft this field by quoting its relevant conventions (runtime choice, commit style, workflow/never-do rules) under a "Conventions inherited from CLAUDE.md" sub-heading, instead of leaving it blank for the user to retype. Present the draft in Step 7 for confirmation rather than asking cold. diff --git a/hooks/lib/primer-init-derive.jq b/hooks/lib/primer-init-derive.jq new file mode 100644 index 0000000..ef3854b --- /dev/null +++ b/hooks/lib/primer-init-derive.jq @@ -0,0 +1,40 @@ +# CONTRACT_VERSION=1 +# hooks/lib/primer-init-derive.jq — pure placeholder-derivation for +# /session-continuity:primer Step 2 (Init mode). Invoked via +# primer-init-derive.sh; see that file for the CLI contract and +# meta/superpowers/specs/2026-09-09-primer-init-derive-design.md for the +# full output contract this implements. + +(if $pkg_name != "" then $pkg_name + elif $cargo_name != "" then $cargo_name + elif $pyproject_name != "" then $pyproject_name + else $dirname end) as $project_name + +| ($git_log | split("\n") | map(select(length > 0)) + | map(if test("^\\S+\\s+.*$") then capture("^(?<hash>\\S+)\\s+(?<subject>.*)$") + else {hash: ., subject: ""} end) + | .[0:5]) as $commits +| ($commits | length) as $commit_count + +| (if $test_cmd == "" then "TBD" + else + ( ($test_output | [scan("[0-9]+ pass(?:ed)?")] | .[0]? + | if . then capture("^(?<n>[0-9]+)").n else null end) as $p + | ($test_output | [scan("[0-9]+ fail(?:ed)?")] | .[0]? + | if . then capture("^(?<n>[0-9]+)").n else null end) as $f + | if $p != null and $f != null then + "`" + $test_cmd + "` — " + $p + " pass / " + $f + " fail" + else + "`" + $test_cmd + "`" + end + ) + end) as $test_summary + +| "PROJECT_NAME=" + $project_name, + "WORKING_DIRECTORY_ABSOLUTE_PATH=" + $pwd, + "COMMIT_COUNT=" + ($commit_count|tostring), + (range(0;5) as $i + | "LATEST_COMMIT_HASH_\($i+1)=" + ($commits[$i].hash // ""), + "LATEST_COMMIT_SUBJECT_\($i+1)=" + ($commits[$i].subject // "")), + "TEST_CMD=" + $test_cmd, + "TEST_COMMAND_SUMMARY=" + $test_summary diff --git a/hooks/lib/primer-init-derive.sh b/hooks/lib/primer-init-derive.sh new file mode 100755 index 0000000..5671178 --- /dev/null +++ b/hooks/lib/primer-init-derive.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/primer-init-derive.sh — placeholder derivation for +# /session-continuity:primer Step 2 (Init mode). See +# meta/superpowers/specs/2026-09-09-primer-init-derive-design.md for the +# full contract this implements and +# meta/superpowers/plans/2026-09-09-primer-init-derive.md for the +# implementation plan. +# +# Usage: TEST_CMD=<cmd> TEST_OUTPUT=<captured output> primer-init-derive.sh <project-dir> +# TEST_CMD/TEST_OUTPUT are read from the environment, not discovered or +# executed here -- commands/primer.md's Step 2 Bash block already discovers +# and runs the test command once and exports both before calling this +# script. Unset/empty is treated as "no test command" (TEST_COMMAND_SUMMARY +# becomes TBD) -- this script never re-runs a test command itself. +# +# Prints KEY=value lines to stdout on success: PROJECT_NAME, +# WORKING_DIRECTORY_ABSOLUTE_PATH, COMMIT_COUNT, LATEST_COMMIT_HASH_1..5, +# LATEST_COMMIT_SUBJECT_1..5, TEST_CMD, TEST_COMMAND_SUMMARY. +# +# Operational failure (jq missing, primer-init-derive.jq missing or from a +# different CONTRACT_VERSION, <project-dir> not a readable directory) prints +# one diagnostic line to stderr and exits 1 with NO PROJECT_NAME= line on +# stdout at all. + +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JQ_FILTER="$SCRIPT_DIR/primer-init-derive.jq" +DIR="${1:-.}" + +die() { # <message> + printf 'primer-init-derive.sh: %s\n' "$1" >&2 + exit 1 +} + +command -v jq >/dev/null 2>&1 \ + || die "jq is not installed, so placeholder derivation cannot run." +[[ -r "$JQ_FILTER" ]] \ + || die "primer-init-derive.jq is missing from $SCRIPT_DIR — the plugin cache is incomplete. Run \`/session-continuity:update\`." +grep -q '^# CONTRACT_VERSION=1$' "$JQ_FILTER" \ + || die "primer-init-derive.jq is from a different plugin version — run \`/session-continuity:update\`." +[[ -d "$DIR" ]] \ + || die "$DIR is not a directory." + +cd "$DIR" || die "cannot cd into $DIR." + +PKG_NAME="" +[[ -f package.json ]] && PKG_NAME="$(grep -m1 '"name"' package.json | sed -E 's/.*"name"[[:space:]]*:[[:space:]]*"([^"]*)".*/\1/')" +CARGO_NAME="" +[[ -f Cargo.toml ]] && CARGO_NAME="$(grep -m1 '^name' Cargo.toml | sed -E 's/^name[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/')" +PYPROJECT_NAME="" +[[ -f pyproject.toml ]] && PYPROJECT_NAME="$(grep -m1 '^name' pyproject.toml | sed -E 's/^name[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/')" +DIRNAME="$(basename "$(pwd)")" + +GIT_LOG="" +if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + GIT_LOG="$(git log --oneline -5 2>/dev/null || true)" +fi + +# TEST_CMD/TEST_OUTPUT are supplied by the caller's environment -- see the +# usage note above. Never discovered or executed here. +TEST_CMD="${TEST_CMD:-}" +TEST_OUTPUT="${TEST_OUTPUT:-}" + +PWD_ABS="$(pwd)" + +ERRFILE="$(mktemp)" +RESULT="$( + jq -r -n \ + --arg pkg_name "$PKG_NAME" \ + --arg cargo_name "$CARGO_NAME" \ + --arg pyproject_name "$PYPROJECT_NAME" \ + --arg dirname "$DIRNAME" \ + --arg pwd "$PWD_ABS" \ + --arg git_log "$GIT_LOG" \ + --arg test_cmd "$TEST_CMD" \ + --arg test_output "$TEST_OUTPUT" \ + -f "$JQ_FILTER" 2>"$ERRFILE" +)" +JQ_STATUS=$? +DETAIL="$(head -1 "$ERRFILE" 2>/dev/null)" +rm -f "$ERRFILE" + +if [[ "$JQ_STATUS" -ne 0 || -z "$RESULT" ]]; then + die "the derivation filter failed: ${DETAIL:-jq exited $JQ_STATUS}" +fi + +printf '%s\n' "$RESULT" diff --git a/meta/superpowers/plans/2026-09-09-primer-init-derive.md b/meta/superpowers/plans/2026-09-09-primer-init-derive.md new file mode 100644 index 0000000..92f1387 --- /dev/null +++ b/meta/superpowers/plans/2026-09-09-primer-init-derive.md @@ -0,0 +1,739 @@ +# Determinism Phase 6, sub-project D — `primer-init-derive.sh`/`.jq` Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace `commands/primer.md` Step 2 item 6's four mechanical +placeholder derivations (`{{PROJECT_NAME}}`, `{{LATEST_COMMIT_HASH_N}}`/ +`{{LATEST_COMMIT_SUBJECT_N}}`, `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}`, +`{{TEST_COMMAND_SUMMARY}}`) with one script, `hooks/lib/primer-init-derive.sh`, +called after the existing raw-fact-gathering Bash block. `{{MODULES_TABLE}}`, +`{{REPO_LAYOUT_SUMMARY}}`, and `{{WORKFLOW_CONVENTIONS}}` are untouched — +excluded per the design's "Problem"/"Non-goals" sections. + +**Architecture:** `primer-init-derive.sh` (bash, I/O — re-derives the +manifest-name and `git log --oneline -5` facts locally, since the existing +Step 2 Bash block never captured those into named variables and re-reading +two files plus one `git log` call is cheap and side-effect-free) hands the +raw text to `primer-init-derive.jq` (pure parse function — no I/O, +fixture-testable with synthetic string args) for the manifest-priority pick, +git-log line split, and pass/fail count regex. `TEST_CMD`/`TEST_OUTPUT` are +the one exception: the existing Bash block already discovers and runs the +test command once, so it exports both, and the script reads them from its +inherited environment rather than rediscovering or re-running anything test- +related — an earlier draft had the script redo that discovery-and-execution +independently, which would have run the project's real test suite twice per +Init-mode invocation; caught before implementation, see the spec's "Test +command: read, never re-run." + +**Spec:** `meta/superpowers/specs/2026-09-09-primer-init-derive-design.md`. + +## Global Constraints + +- `primer-init-derive.sh` and `primer-init-derive.jq` both carry a + `# CONTRACT_VERSION=1` header. `commands/primer.md` calls the `.sh` + through `require_script`, exactly like `primer-detect.sh` and + `test-count-rerun.sh` already are. `primer-init-derive.sh` itself checks + its sibling `.jq`'s `CONTRACT_VERSION` before invoking it. +- **No fabricated derivation on operational failure.** jq missing, the `.jq` + filter missing/version-mismatched, or `<project-dir>` unreadable each print + one diagnostic line to stderr and exit nonzero with no `PROJECT_NAME=` line + on stdout. `commands/primer.md` falls back to asking the user for the + affected fields manually — it must not invent a project name, commit list, + or test summary. +- **Never invent a test count.** `TEST_COMMAND_SUMMARY` includes a fail count + only when a fail-count regex match was actually found in the captured + output — never defaulted to `0`. See spec's "`TEST_COMMAND_SUMMARY` rules." +- Both count regexes (`[0-9]+ pass(ed)?`, `[0-9]+ fail(ed)?`) are copied + verbatim in spirit from `hooks/lib/test-count-rerun.sh`'s `run_once()` — + same pattern, same `head -1` first-match convention — not re-derived from + scratch, so the two scripts recognize test output identically. +- **Never re-run the test command.** `primer-init-derive.sh` reads + `TEST_CMD`/`TEST_OUTPUT` from its inherited environment — exported by + `commands/primer.md`'s existing Bash block right after it runs the + command once — and does not discover or execute a test command itself. + Running the project's real test suite twice per Init-mode invocation is + not an acceptable cost of this refactor. +- **Every git-log line yields exactly one `commits[]` entry, parseable or + not.** `capture(re)` with no match produces zero outputs in jq — a naive + `map(capture(...))` silently drops non-matching lines, shrinking + `COMMIT_COUNT` and shifting every following commit's index. Guard with + `test(...)` first; fall back to a hash-only entry on no match. +- The raw-fact-gathering Bash block in `commands/primer.md` Step 2 item 6 + (manifest checks, `git log --oneline -5`, the `@module` grep, test-command + discovery and execution) stays exactly as it is except for one added line + exporting `TEST_CMD TEST_OUTPUT` — this plan only replaces what reads that + output afterward, and only for the four fields named above. +- Do not touch `{{MODULES_TABLE}}`, `{{REPO_LAYOUT_SUMMARY}}`, or + `{{WORKFLOW_CONVENTIONS}}` — prose, unchanged, per the spec's Non-goals. +- Do not touch `hooks/lib/primer-detect.sh`/`.jq` (sub-project A), + `hooks/lib/test-count-rerun.sh`/`.jq` (sub-project B), or + `hooks/lib/token-overlap.sh`/`.jq` (Phase 5) — unrelated to this plan. + +--- + +## File Structure + +| File | Responsibility | +|---|---| +| `hooks/lib/primer-init-derive.jq` (new) | Pure parse function: given manifest name-lines, a git-log block, and a test-run's captured output as string args, computes `PROJECT_NAME`, `LATEST_COMMIT_HASH_N`/`SUBJECT_N` (1-5), `TEST_COMMAND_SUMMARY`. No I/O. | +| `hooks/lib/primer-init-derive.sh` (new) | I/O: re-runs the manifest/git-log/test-command gathering already described in `commands/primer.md` Step 2 item 6, passes raw text to the filter. | +| `commands/primer.md` (modified) | Step 2 item 6's four mechanical bullets collapse to one script call; the `{{MODULES_TABLE}}`, `{{REPO_LAYOUT_SUMMARY}}`, `{{WORKFLOW_CONVENTIONS}}` bullets are untouched. | +| `meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh` (new) | Smoke test: `.jq`-only fixtures (synthetic string args, no git/subprocess) plus `.sh` integration fixtures (scratch git repos with real manifests and a fake `TEST_CMD`) plus operational-failure cases. | +| `meta/superpowers/specs/2026-09-02-determinism-program-design.md` (modified) | Phase 6 entry notes sub-project D shipped; C/E remain pending. | +| `CHANGELOG.md` (modified) | New version entry. | +| `.claude-plugin/plugin.json` (modified) | Version bump `0.33.0` → `0.34.0`. | + +--- + +### Task 1: `hooks/lib/primer-init-derive.jq` + `hooks/lib/primer-init-derive.sh` + +**Files:** +- Create: `hooks/lib/primer-init-derive.jq` +- Create: `hooks/lib/primer-init-derive.sh` +- Test: `meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh` + +**Interfaces:** +- Produces: `bash primer-init-derive.sh <project-dir>`. Prints `KEY=value` + lines to stdout per the spec's Output contract (`PROJECT_NAME`, + `WORKING_DIRECTORY_ABSOLUTE_PATH`, `COMMIT_COUNT`, + `LATEST_COMMIT_HASH_1..5`, `LATEST_COMMIT_SUBJECT_1..5`, `TEST_CMD`, + `TEST_COMMAND_SUMMARY`). Exits 0 on success. On operational failure, + prints one diagnostic line to stderr and exits 1 with **no** + `PROJECT_NAME=` line anywhere in stdout. +- Consumes: `jq` (hard dependency), `git`. Reads `TEST_CMD`/`TEST_OUTPUT` + from its inherited environment — does not itself run a test command, so + it has no `timeout` dependency. + +- [ ] **Step 1: Write the failing smoke test** + +Create `meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh`: + +```zsh +#!/usr/bin/env zsh +# primer-init-derive.sh/.jq smoke test. Two layers: +# Part A: .jq fixtures via synthetic string args (no git, no subprocess) -- +# the manifest-priority pick, git-log split, count-regex matrix. +# Part B: .sh integration fixtures via scratch git repos with real +# manifests and a fake TEST_CMD -- gathering + end-to-end wiring. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +jq_filter="$lib/primer-init-derive.jq" +tool="$lib/primer-init-derive.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +# --------------------------------------------------------------------------- +# Part A: .jq fixtures +# --------------------------------------------------------------------------- + +# jq_run <pkg_name> <cargo_name> <pyproject_name> <dirname> <git_log> <test_cmd> <test_output> +jq_run() { + jq -r -n \ + --arg pkg_name "$1" --arg cargo_name "$2" --arg pyproject_name "$3" \ + --arg dirname "$4" --arg pwd "/tmp/$4" --arg git_log "$5" \ + --arg test_cmd "$6" --arg test_output "$7" \ + -f "$jq_filter" +} +jq_field() { # <output> <KEY> -> value + print -r -- "$1" | awk -F= -v k="$2" '$1==k{print substr($0, length(k)+2)}' +} + +# A1: package.json name wins over Cargo.toml even when both present +out="$(jq_run pkgname cratename "" dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "pkgname" ]] \ + && ok "A1: package.json name wins priority" || bad "A1: got '$out'" + +# A2: only Cargo.toml present +out="$(jq_run "" cratename "" dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "cratename" ]] \ + && ok "A2: Cargo.toml name used when package.json absent" || bad "A2: got '$out'" + +# A3: only pyproject.toml present +out="$(jq_run "" "" pyname dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "pyname" ]] \ + && ok "A3: pyproject.toml name used when others absent" || bad "A3: got '$out'" + +# A4: no manifest -> directory basename fallback +out="$(jq_run "" "" "" dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "dirfallback" ]] \ + && ok "A4: directory basename fallback" || bad "A4: got '$out'" + +# A5: 5-line git log -> COMMIT_COUNT=5, all pairs filled +gitlog5=$'aaa1111 first commit\nbbb2222 second commit\nccc3333 third\nddd4444 fourth\neee5555 fifth' +out="$(jq_run pkg "" "" dir "$gitlog5" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "5" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_1)" == "aaa1111" \ + && "$(jq_field "$out" LATEST_COMMIT_SUBJECT_1)" == "first commit" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_5)" == "eee5555" ]] \ + && ok "A5: 5-commit log fully split" || bad "A5: got '$out'" + +# A6: 2-line git log (fresh repo) -> COMMIT_COUNT=2, pairs 3-5 empty +gitlog2=$'aaa1111 only commit\nbbb2222 init' +out="$(jq_run pkg "" "" dir "$gitlog2" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "2" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_3)" == "" \ + && "$(jq_field "$out" LATEST_COMMIT_SUBJECT_5)" == "" ]] \ + && ok "A6: 2-commit log leaves 3-5 empty" || bad "A6: got '$out'" + +# A7: empty git log (no commits yet) -> COMMIT_COUNT=0, all empty +out="$(jq_run pkg "" "" dir "" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "0" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_1)" == "" ]] \ + && ok "A7: empty git log -> COMMIT_COUNT=0" || bad "A7: got '$out'" + +# A8: empty TEST_CMD -> TBD +out="$(jq_run pkg "" "" dir "" "" "")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == "TBD" ]] \ + && ok "A8: no test command -> TBD" || bad "A8: got '$out'" + +# A9: pass + fail both parseable -> full summary +out="$(jq_run pkg "" "" dir "" "bun test" "12 pass, 0 fail")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`bun test` — 12 pass / 0 fail' ]] \ + && ok "A9: pass+fail parseable -> full summary" || bad "A9: got '$out'" + +# A10: pass parseable, fail not -> bare command, no invented fail count +out="$(jq_run pkg "" "" dir "" "bun test" "12 pass")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`bun test`' ]] \ + && ok "A10: pass only, no fail match -> bare command" || bad "A10: got '$out'" + +# A11: no recognizable count anywhere -> bare command +out="$(jq_run pkg "" "" dir "" "bun test" "something went wrong, no counts here")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`bun test`' ]] \ + && ok "A11: no parseable count -> bare command" || bad "A11: got '$out'" + +# A12: pytest-style "N passed, M failed" phrasing +out="$(jq_run pkg "" "" dir "" "pytest" "5 passed, 1 failed in 0.42s")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`pytest` — 5 pass / 1 fail' ]] \ + && ok "A12: pytest phrasing parses" || bad "A12: got '$out'" + +# A13: a git-log line with no whitespace at all (no parseable subject) +# still yields exactly one commits[] entry instead of being silently +# dropped by a bare map(capture(...)). +gitlog_nospace=$'aaa1111 real commit\nnospacehash' +out="$(jq_run pkg "" "" dir "$gitlog_nospace" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "2" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_2)" == "nospacehash" \ + && "$(jq_field "$out" LATEST_COMMIT_SUBJECT_2)" == "" ]] \ + && ok "A13: non-matching git-log line still yields one commits[] entry" || bad "A13: got '$out'" + +# --------------------------------------------------------------------------- +# Part B: .sh integration fixtures +# --------------------------------------------------------------------------- + +# mk_repo <dir> [package.json contents] +mk_repo() { + local dir="$1" + rm -rf "$dir"; mkdir -p "$dir" + git -C "$dir" init -q + git -C "$dir" config user.email test@example.com + git -C "$dir" config user.name Test + print -r -- "init" > "$dir/README.md" + git -C "$dir" add -A; git -C "$dir" commit -qm "init commit" + print -r -- "second" >> "$dir/README.md" + git -C "$dir" add -A; git -C "$dir" commit -qm "second commit" +} + +# B1: package.json present -> PROJECT_NAME from it, real git log split +d="$work/b1"; mk_repo "$d" +print -r -- '{"name": "real-pkg-name"}' > "$d/package.json" +git -C "$d" add -A; git -C "$d" commit -qm "add package.json" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" PROJECT_NAME)" == "real-pkg-name" \ + && "$(jq_field "$out" COMMIT_COUNT)" == "3" ]] \ + && ok "B1: real package.json + git log wired end to end" || bad "B1: got '$out'" + +# B2: no manifest -> directory basename fallback +d="$work/b2-namedrepo"; mk_repo "$d" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" PROJECT_NAME)" == "b2-namedrepo" ]] \ + && ok "B2: no manifest -> real directory basename" || bad "B2: got '$out'" + +# B3: WORKING_DIRECTORY_ABSOLUTE_PATH matches the real path +d="$work/b3"; mk_repo "$d" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" WORKING_DIRECTORY_ABSOLUTE_PATH)" == "$d" ]] \ + && ok "B3: WORKING_DIRECTORY_ABSOLUTE_PATH is the real path" || bad "B3: got '$out'" + +# B4: TEST_CMD/TEST_OUTPUT come from the environment, not from a real run -- +# the tool must never itself execute a test command, so a TEST_CMD naming a +# script that (if actually run) would fail the whole smoke test is a +# deliberate canary: if the tool ever re-introduces its own execution, this +# assertion starts failing loudly instead of just timing out quietly. +d="$work/b4"; mk_repo "$d" +out="$(cd "$d" && TEST_CMD='exit 1; echo THIS_MUST_NEVER_RUN' TEST_OUTPUT='7 passed, 1 failed' bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" TEST_CMD)" == 'exit 1; echo THIS_MUST_NEVER_RUN' \ + && "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`exit 1; echo THIS_MUST_NEVER_RUN` — 7 pass / 1 fail' ]] \ + && ok "B4: TEST_CMD/TEST_OUTPUT read from env, never executed" || bad "B4: got '$out'" + +# B5: no TEST_CMD in the environment -> TBD, same as the no-manifest case +d="$work/b5"; mk_repo "$d" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == "TBD" ]] \ + && ok "B5: no TEST_CMD in environment -> TBD" || bad "B5: got '$out'" + +# --------------------------------------------------------------------------- +# Operational failure cases +# --------------------------------------------------------------------------- + +# B6: missing .jq filter +d="$work/b6"; mk_repo "$d" +badlib="$work/badlib"; mkdir -p "$badlib"; cp "$tool" "$badlib/" +out="$(cd "$d" && bash "$badlib/primer-init-derive.sh" "$d" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"PROJECT_NAME="* ]] \ + && ok "B6: missing filter -> nonzero exit, no PROJECT_NAME= line" || bad "B6: rc=$rc out='$out'" + +# B7: wrong CONTRACT_VERSION +d="$work/b7"; mk_repo "$d" +wronglib="$work/wronglib"; mkdir -p "$wronglib"; cp "$tool" "$wronglib/" +sed 's/CONTRACT_VERSION=1/CONTRACT_VERSION=99/' "$jq_filter" > "$wronglib/primer-init-derive.jq" +out="$(cd "$d" && bash "$wronglib/primer-init-derive.sh" "$d" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"PROJECT_NAME="* ]] \ + && ok "B7: wrong CONTRACT_VERSION -> nonzero exit, no PROJECT_NAME= line" || bad "B7: rc=$rc out='$out'" + +# B8: jq absent from PATH +d="$work/b8"; mk_repo "$d" +nojq="$work/nojq"; mkdir -p "$nojq/bin" +for b in bash git awk grep sed head cat mktemp dirname timeout wc tr; do + p="$(command -v "$b")"; [[ -n "$p" ]] && ln -sf "$p" "$nojq/bin/$b" +done +out="$(cd "$d" && PATH="$nojq/bin" bash "$tool" "$d" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"PROJECT_NAME="* ]] \ + && ok "B8: jq absent from PATH -> nonzero exit, no PROJECT_NAME= line" || bad "B8: rc=$rc out='$out'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) +``` + +- [ ] **Step 2: Run it to verify it fails** + +```bash +chmod +x meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh +``` + +Expected: FAIL on every assertion — neither +`hooks/lib/primer-init-derive.jq` nor `hooks/lib/primer-init-derive.sh` +exists yet. + +- [ ] **Step 3: Write `hooks/lib/primer-init-derive.jq`** + +```jq +# CONTRACT_VERSION=1 +# hooks/lib/primer-init-derive.jq — pure placeholder-derivation for +# /session-continuity:primer Step 2 (Init mode). Invoked via +# primer-init-derive.sh; see that file for the CLI contract and +# meta/superpowers/specs/2026-09-09-primer-init-derive-design.md for the +# full output contract this implements. + +(if $pkg_name != "" then $pkg_name + elif $cargo_name != "" then $cargo_name + elif $pyproject_name != "" then $pyproject_name + else $dirname end) as $project_name + +| ($git_log | split("\n") | map(select(length > 0)) + | map(if test("^\\S+\\s+.*$") then capture("^(?<hash>\\S+)\\s+(?<subject>.*)$") + else {hash: ., subject: ""} end) + | .[0:5]) as $commits +| ($commits | length) as $commit_count + +| (if $test_cmd == "" then "TBD" + else + ( ($test_output | [scan("[0-9]+ pass(?:ed)?")] | .[0]? + | if . then capture("^(?<n>[0-9]+)").n else null end) as $p + | ($test_output | [scan("[0-9]+ fail(?:ed)?")] | .[0]? + | if . then capture("^(?<n>[0-9]+)").n else null end) as $f + | if $p != null and $f != null then + "`" + $test_cmd + "` — " + $p + " pass / " + $f + " fail" + else + "`" + $test_cmd + "`" + end + ) + end) as $test_summary + +| "PROJECT_NAME=" + $project_name, + "WORKING_DIRECTORY_ABSOLUTE_PATH=" + $pwd, + "COMMIT_COUNT=" + ($commit_count|tostring), + (range(0;5) as $i + | "LATEST_COMMIT_HASH_\($i+1)=" + ($commits[$i].hash // ""), + "LATEST_COMMIT_SUBJECT_\($i+1)=" + ($commits[$i].subject // "")), + "TEST_CMD=" + $test_cmd, + "TEST_COMMAND_SUMMARY=" + $test_summary +``` + +Note: `scan("[0-9]+ pass(?:ed)?")` returns the full matched substring (e.g. +`"12 pass"`), so it needs its own `capture("^(?<n>[0-9]+)")` to pull just the +digits — this mirrors `test-count-rerun.sh`'s two-regex `grep | grep` pipe +(`[0-9]+ pass(ed)?` then `^[0-9]+`) translated into jq's regex functions, +same two-step extraction, same reason (the first regex finds the phrase, +the second isolates the number from it). + +Note: the commit-line `if test(...) then capture(...) else {hash:., subject:""} end` +guard exists because `capture(re)` with no match produces **zero outputs**, +not an error and not `null` — confirmed directly: `jq -n '"onetoken" | +capture("^(?<hash>\\S+)\\s+(?<subject>.*)$")'` exits 0 and prints nothing. +A bare `map(capture(...))` would silently drop any line that doesn't match +`<hash><space><subject>`, shrinking `$commits`'s length below the number of +real git-log lines and shifting every subsequent commit into the wrong `_N` +slot. The guard verified against both a no-space line (`"aaa1111"` → +`{hash:"aaa1111", subject:""}`) and a normal line, so `$commits`'s length +always equals the input's non-empty line count. + +- [ ] **Step 4: Write `hooks/lib/primer-init-derive.sh`** + +```bash +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# hooks/lib/primer-init-derive.sh — placeholder derivation for +# /session-continuity:primer Step 2 (Init mode). See +# meta/superpowers/specs/2026-09-09-primer-init-derive-design.md for the +# full contract this implements and +# meta/superpowers/plans/2026-09-09-primer-init-derive.md for the +# implementation plan. +# +# Usage: TEST_CMD=<cmd> TEST_OUTPUT=<captured output> primer-init-derive.sh <project-dir> +# TEST_CMD/TEST_OUTPUT are read from the environment, not discovered or +# executed here -- commands/primer.md's Step 2 Bash block already discovers +# and runs the test command once and exports both before calling this +# script. Unset/empty is treated as "no test command" (TEST_COMMAND_SUMMARY +# becomes TBD) -- this script never re-runs a test command itself. +# +# Prints KEY=value lines to stdout on success: PROJECT_NAME, +# WORKING_DIRECTORY_ABSOLUTE_PATH, COMMIT_COUNT, LATEST_COMMIT_HASH_1..5, +# LATEST_COMMIT_SUBJECT_1..5, TEST_CMD, TEST_COMMAND_SUMMARY. +# +# Operational failure (jq missing, primer-init-derive.jq missing or from a +# different CONTRACT_VERSION, <project-dir> not a readable directory) prints +# one diagnostic line to stderr and exits 1 with NO PROJECT_NAME= line on +# stdout at all. + +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JQ_FILTER="$SCRIPT_DIR/primer-init-derive.jq" +DIR="${1:-.}" + +die() { # <message> + printf 'primer-init-derive.sh: %s\n' "$1" >&2 + exit 1 +} + +command -v jq >/dev/null 2>&1 \ + || die "jq is not installed, so placeholder derivation cannot run." +[[ -r "$JQ_FILTER" ]] \ + || die "primer-init-derive.jq is missing from $SCRIPT_DIR — the plugin cache is incomplete. Run \`/session-continuity:update\`." +grep -q '^# CONTRACT_VERSION=1$' "$JQ_FILTER" \ + || die "primer-init-derive.jq is from a different plugin version — run \`/session-continuity:update\`." +[[ -d "$DIR" ]] \ + || die "$DIR is not a directory." + +cd "$DIR" || die "cannot cd into $DIR." + +PKG_NAME="" +[[ -f package.json ]] && PKG_NAME="$(grep -m1 '"name"' package.json | sed -E 's/.*"name"[[:space:]]*:[[:space:]]*"([^"]*)".*/\1/')" +CARGO_NAME="" +[[ -f Cargo.toml ]] && CARGO_NAME="$(grep -m1 '^name' Cargo.toml | sed -E 's/^name[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/')" +PYPROJECT_NAME="" +[[ -f pyproject.toml ]] && PYPROJECT_NAME="$(grep -m1 '^name' pyproject.toml | sed -E 's/^name[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/')" +DIRNAME="$(basename "$(pwd)")" + +GIT_LOG="" +if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + GIT_LOG="$(git log --oneline -5 2>/dev/null || true)" +fi + +# TEST_CMD/TEST_OUTPUT are supplied by the caller's environment -- see the +# usage note above. Never discovered or executed here. +TEST_CMD="${TEST_CMD:-}" +TEST_OUTPUT="${TEST_OUTPUT:-}" + +PWD_ABS="$(pwd)" + +ERRFILE="$(mktemp)" +RESULT="$( + jq -r -n \ + --arg pkg_name "$PKG_NAME" \ + --arg cargo_name "$CARGO_NAME" \ + --arg pyproject_name "$PYPROJECT_NAME" \ + --arg dirname "$DIRNAME" \ + --arg pwd "$PWD_ABS" \ + --arg git_log "$GIT_LOG" \ + --arg test_cmd "$TEST_CMD" \ + --arg test_output "$TEST_OUTPUT" \ + -f "$JQ_FILTER" 2>"$ERRFILE" +)" +JQ_STATUS=$? +DETAIL="$(head -1 "$ERRFILE" 2>/dev/null)" +rm -f "$ERRFILE" + +if [[ "$JQ_STATUS" -ne 0 || -z "$RESULT" ]]; then + die "the derivation filter failed: ${DETAIL:-jq exited $JQ_STATUS}" +fi + +printf '%s\n' "$RESULT" +``` + +```bash +chmod +x hooks/lib/primer-init-derive.sh +``` + +- [ ] **Step 5: Run the smoke test to verify all assertions pass** + +```bash +zsh meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh +``` + +Expected: `Result: 21 passed, 0 failed`. + +- [ ] **Step 6: Commit** + +```bash +git add hooks/lib/primer-init-derive.jq hooks/lib/primer-init-derive.sh meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh +git commit -m "feat: add primer-init-derive.sh/.jq, scripting primer Step 2's placeholder derivation" +``` + +--- + +### Task 2: `commands/primer.md` — call the script + +**Files:** +- Modify: `commands/primer.md` (Step 2 item 6, currently lines 75-117 as of + `eee17b8`) + +**Interfaces:** +- Consumes: `hooks/lib/primer-init-derive.sh` (Task 1), resolved via + `CLAUDE_PLUGIN_ROOT` and `require_script`, exactly like `primer-detect.sh` + and `test-count-rerun.sh` already are. + +- [ ] **Step 1: Replace item 6 in full** + +Using the Edit tool, replace this exact block (currently `commands/primer.md` +lines 75-117 as of `eee17b8`, from `6. Fill in placeholders...` through the +`{{WORKFLOW_CONVENTIONS}} (draft)` bullet): + +````markdown +6. Fill in placeholders Claude can derive automatically. Gather the raw + data in **one Bash call**, timed: + + ```bash + _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + pwd + basename "$(pwd)" + [ -f package.json ] && grep -m1 '"name"' package.json + [ -f Cargo.toml ] && grep -m1 '^name' Cargo.toml + [ -f pyproject.toml ] && grep -m1 '^name' pyproject.toml + git log --oneline -5 + [ -f package.json ] && grep -A1 '"scripts"' package.json | grep '"test"' + find . -maxdepth 2 -not -path './node_modules/*' -not -path './.git/*' + [ -f CLAUDE.md ] && echo "--- CLAUDE.md ---" && cat CLAUDE.md + grep -rn -B1 -A2 '@module' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' -- src lib 2>/dev/null | head -100 + TEST_CMD="" + if [ -f package.json ]; then + TEST_CMD=$(grep -A1 '"scripts"' package.json | grep '"test"' | sed -E 's/.*"test":[[:space:]]*"([^"]+)".*/\1/') + elif [ -f Cargo.toml ] && command -v cargo >/dev/null 2>&1; then + TEST_CMD="cargo test" + elif [ -f pyproject.toml ] && command -v pytest >/dev/null 2>&1; then + TEST_CMD="pytest" + fi + if [ -n "$TEST_CMD" ]; then + echo "--- test run: $TEST_CMD ---" + TEST_OUTPUT=$(timeout 120 bash -c "$TEST_CMD" 2>&1) + TEST_EXIT=$? + echo "$TEST_OUTPUT" | tail -20 + echo "TEST_RUN_EXIT=$TEST_EXIT" + fi + _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-2-init-derive-placeholders --duration="$_PERF_DURATION" + ``` + + Derive from that output: + - `{{PROJECT_NAME}}` — from `package.json` `name`, `Cargo.toml` `name`, `pyproject.toml` `name`, or the current directory basename. + - `{{LATEST_COMMIT_HASH_N}}` / `{{LATEST_COMMIT_SUBJECT_N}}` — from the `git log --oneline -5` output above. + - `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}` — from the `pwd` output above. + - `{{TEST_COMMAND_SUMMARY}}` — if `TEST_RUN_EXIT=0` and the captured output contains a recognizable count (`N pass`, `N passed`, `test result: ok. N passed`, etc.), seed this as "`<TEST_CMD>` — N pass / M fail" from that single run. If `TEST_CMD` was empty, the run timed out (`TEST_RUN_EXIT=124`), or the output has no parseable count, fall back to the bare `scripts.test` string (or `TBD`) — never invent a count. + - `{{REPO_LAYOUT_SUMMARY}}` — from the `find` output above, plus a one-line description Claude infers from the file extensions present. + - `{{MODULES_TABLE}}` — if the `@module` grep above found matches, build one table row per file: Component = file path, Purpose = the `@module` value (plus the docblock's one-line description if present), Notes = the adjacent `Exports:` line if present. If it found nothing, leave `TBD` as before — don't invent structure that isn't there. + - `{{WORKFLOW_CONVENTIONS}} (draft)` — if `CLAUDE.md` exists (cat output above), draft this field by quoting its relevant conventions (runtime choice, commit style, workflow/never-do rules) under a "Conventions inherited from CLAUDE.md" sub-heading, instead of leaving it blank for the user to retype. Present the draft in Step 7 for confirmation rather than asking cold. +```` + +with: + +````markdown +6. Fill in placeholders Claude can derive automatically. Gather the raw + data in **one Bash call**, timed: + + ```bash + _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + pwd + basename "$(pwd)" + [ -f package.json ] && grep -m1 '"name"' package.json + [ -f Cargo.toml ] && grep -m1 '^name' Cargo.toml + [ -f pyproject.toml ] && grep -m1 '^name' pyproject.toml + git log --oneline -5 + [ -f package.json ] && grep -A1 '"scripts"' package.json | grep '"test"' + find . -maxdepth 2 -not -path './node_modules/*' -not -path './.git/*' + [ -f CLAUDE.md ] && echo "--- CLAUDE.md ---" && cat CLAUDE.md + grep -rn -B1 -A2 '@module' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' -- src lib 2>/dev/null | head -100 + TEST_CMD="" + if [ -f package.json ]; then + TEST_CMD=$(grep -A1 '"scripts"' package.json | grep '"test"' | sed -E 's/.*"test":[[:space:]]*"([^"]+)".*/\1/') + elif [ -f Cargo.toml ] && command -v cargo >/dev/null 2>&1; then + TEST_CMD="cargo test" + elif [ -f pyproject.toml ] && command -v pytest >/dev/null 2>&1; then + TEST_CMD="pytest" + fi + if [ -n "$TEST_CMD" ]; then + echo "--- test run: $TEST_CMD ---" + TEST_OUTPUT=$(timeout 120 bash -c "$TEST_CMD" 2>&1) + TEST_EXIT=$? + echo "$TEST_OUTPUT" | tail -20 + echo "TEST_RUN_EXIT=$TEST_EXIT" + fi + _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") + _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-2-init-derive-placeholders --duration="$_PERF_DURATION" + export TEST_CMD TEST_OUTPUT + source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-init-derive.sh" 1; then + DERIVE_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-init-derive.sh" . 2>&1)" + DERIVE_STATUS=$? + else + DERIVE_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + DERIVE_STATUS=1 + fi + echo "$DERIVE_OUTPUT" + echo "DERIVE_STATUS=$DERIVE_STATUS" + ``` + + **If `DERIVE_STATUS` is nonzero, or `$DERIVE_OUTPUT` has no + `PROJECT_NAME=` line:** report `$DERIVE_OUTPUT` to the user and ask for + `{{PROJECT_NAME}}`, the commit placeholders, and `{{TEST_COMMAND_SUMMARY}}` + manually in Step 7 below — never fabricate these from a failed script. + + **Otherwise**, fill directly from `$DERIVE_OUTPUT`'s fields: + - `{{PROJECT_NAME}}` — `PROJECT_NAME`. + - `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}` — `WORKING_DIRECTORY_ABSOLUTE_PATH`. + - `{{LATEST_COMMIT_HASH_N}}` / `{{LATEST_COMMIT_SUBJECT_N}}` — for each + `N` from 1 to `COMMIT_COUNT`, `LATEST_COMMIT_HASH_N` / + `LATEST_COMMIT_SUBJECT_N`. If `COMMIT_COUNT` is below 5, leave the + template's remaining `N` slots as `TBD` rather than writing empty pairs. + - `{{TEST_COMMAND_SUMMARY}}` — `TEST_COMMAND_SUMMARY`, verbatim. + - `{{REPO_LAYOUT_SUMMARY}}` — from the `find` output above, plus a one-line description Claude infers from the file extensions present. + - `{{MODULES_TABLE}}` — if the `@module` grep above found matches, build one table row per file: Component = file path, Purpose = the `@module` value (plus the docblock's one-line description if present), Notes = the adjacent `Exports:` line if present. If it found nothing, leave `TBD` as before — don't invent structure that isn't there. + - `{{WORKFLOW_CONVENTIONS}} (draft)` — if `CLAUDE.md` exists (cat output above), draft this field by quoting its relevant conventions (runtime choice, commit style, workflow/never-do rules) under a "Conventions inherited from CLAUDE.md" sub-heading, instead of leaving it blank for the user to retype. Present the draft in Step 7 for confirmation rather than asking cold. +```` + +Note what changed and what didn't: the raw gathering Bash block is +byte-for-byte identical through the `fi` that closes the test-run block; +only three lines are added after the existing `perf-log.sh record` call +(`export TEST_CMD TEST_OUTPUT`, the `require_script`/script-call block, and +the two `echo` lines). The `{{REPO_LAYOUT_SUMMARY}}`, `{{MODULES_TABLE}}`, +and `{{WORKFLOW_CONVENTIONS}} (draft)` bullets are carried over verbatim, +unchanged — only the four mechanical bullets above them are replaced. + +- [ ] **Step 2: Verify the old prose is gone** + +```bash +grep -c 'from the .git log --oneline -5. output above\|seed this as' commands/primer.md +``` + +Expected: `0` — the derivation mechanics now live only in +`primer-init-derive.jq`, referenced by its output fields everywhere else. + +- [ ] **Step 3: Commit** + +```bash +git add commands/primer.md +git commit -m "refactor: primer.md Step 2 item 6 dispatches via primer-init-derive.sh" +``` + +--- + +### Task 3: Doc pointers, regression pass, changelog + +**Files:** +- Modify: `meta/superpowers/specs/2026-09-02-determinism-program-design.md` +- Modify: `CHANGELOG.md` +- Modify: `.claude-plugin/plugin.json` + +- [ ] **Step 1: Update the design doc's Phase 6 entry** + +Using the Edit tool, replace the "Still pending: C ... D ... E ..." sentence +at the end of the Phase 6 entry in +`meta/superpowers/specs/2026-09-02-determinism-program-design.md` with a +version that adds "**Sub-project D shipped** — Step 2's placeholder +derivation (`{{PROJECT_NAME}}`, commit hash/subject pairs, +`{{TEST_COMMAND_SUMMARY}}`), now `hooks/lib/primer-init-derive.sh`/`.jq`. +Spec: `meta/superpowers/specs/2026-09-09-primer-init-derive-design.md`. Plan: +`meta/superpowers/plans/2026-09-09-primer-init-derive.md`." and narrows +"Still pending" to just C and E. + +- [ ] **Step 2: Full regression pass** + +```bash +for f in \ + meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh \ + meta/superpowers/validation/2026-09-09-test-count-rerun-smoke.zsh \ + meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh \ + meta/superpowers/validation/2026-09-08-checklist-assemble-smoke.zsh \ + meta/superpowers/validation/2026-08-17-perf-log-smoke.zsh \ + meta/superpowers/validation/2026-09-03-primer-status-smoke.zsh \ + meta/superpowers/validation/2026-08-12-session-start-smoke.zsh \ + meta/superpowers/validation/2026-09-01-require-script-smoke.zsh \ + meta/superpowers/validation/2026-09-07-backlog-issues-smoke.zsh \ + meta/superpowers/validation/2026-09-01-agent-active-smoke.zsh \ + meta/superpowers/validation/2026-09-02-resolve-transcript-smoke.zsh \ + meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh \ + meta/superpowers/validation/2026-09-02-candidate-render-smoke.zsh \ + meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh +do + echo "--- $f ---" + zsh "$f" || echo "FAILED: $f" +done +``` + +Expected: every runner ends `0 failed`. + +- [ ] **Step 3: Add a CHANGELOG entry** + +Add a new section at the top of `CHANGELOG.md`, directly under the +`# Changelog` header and its description line: + +```markdown +## [0.34.0] — 2026-09-09 + +### Changed +- **`/session-continuity:primer`'s Step 2 placeholder derivation is now + scripted.** New `hooks/lib/primer-init-derive.sh`/`.jq` replace four + hand-evaluated derivations (`{{PROJECT_NAME}}`'s manifest-priority pick, + `{{LATEST_COMMIT_HASH_N}}`/`{{LATEST_COMMIT_SUBJECT_N}}`'s git-log split, + `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}`'s passthrough, + `{{TEST_COMMAND_SUMMARY}}`'s pass/fail-count regex) with one script call. + `{{MODULES_TABLE}}`'s docblock parsing, `{{REPO_LAYOUT_SUMMARY}}`'s + inferred sentence, and `{{WORKFLOW_CONVENTIONS}}`'s draft stay prose — + each depends on arbitrary per-project convention, not a fixed format, the + same reasoning that already excluded the latter two from this program. + Determinism Phase 6 (#43) sub-project D; sub-projects C and E remain + pending. +``` + +- [ ] **Step 4: Bump the plugin version** + +Using the Edit tool, update `.claude-plugin/plugin.json`'s `"version"` field +from `"0.33.0"` to `"0.34.0"`. + +- [ ] **Step 5: Commit** + +```bash +git add meta/superpowers/specs/2026-09-02-determinism-program-design.md CHANGELOG.md .claude-plugin/plugin.json +git commit -m "docs: Phase 6 sub-project D doc pointers, changelog, and version bump" +``` diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index 63c78bb..16cfabf 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -214,12 +214,16 @@ shipped** — Step 4's test-count majority-vote rerun (the compare-a-claimed-value-against-an-actual-one class Phase 7 is being built to gate against), now `hooks/lib/test-count-rerun.sh`/`.jq`. Spec: `meta/superpowers/specs/2026-09-09-test-count-rerun-design.md`. Plan: -`meta/superpowers/plans/2026-09-09-test-count-rerun.md`. Still pending: +`meta/superpowers/plans/2026-09-09-test-count-rerun.md`. **Sub-project D +shipped** — Step 2's placeholder derivation (`{{PROJECT_NAME}}`, commit +hash/subject pairs, `{{TEST_COMMAND_SUMMARY}}`), now +`hooks/lib/primer-init-derive.sh`/`.jq`. Spec: +`meta/superpowers/specs/2026-09-09-primer-init-derive-design.md`. Plan: +`meta/superpowers/plans/2026-09-09-primer-init-derive.md`. Still pending: C (Step 3c/3d's `git mv`/`git rm` migration mechanics themselves — -sub-project A only scripted *whether* they run, not *what* they do), D -(Step 2's placeholder-derivation gather-and-regex), E (Step 3/3b's -section-bucketing judgment, lowest priority — near-zero remaining -audience, most judgment-heavy of the five). +sub-project A only scripted *whether* they run, not *what* they do) and E +(Step 3/3b's section-bucketing judgment, lowest priority — near-zero +remaining audience, most judgment-heavy of the five). **Phase 7 `#44` — the gate that keeps it true.** A commit-time content gate on staged `commands/*.md` that blocks prompt text instructing a model to count, diff --git a/meta/superpowers/specs/2026-09-09-primer-init-derive-design.md b/meta/superpowers/specs/2026-09-09-primer-init-derive-design.md new file mode 100644 index 0000000..92c294e --- /dev/null +++ b/meta/superpowers/specs/2026-09-09-primer-init-derive-design.md @@ -0,0 +1,254 @@ +# Determinism Phase 6, sub-project D — `primer-init-derive.sh`/`.jq` Design + +## Context + +Phase 6 (`#43`) decomposes into five sub-projects — see +`meta/superpowers/specs/2026-09-08-primer-detect-design.md`'s Context section +for the full breakdown. A (Step 1 detect/dispatch) and B (Step 4 test-count +rerun) are shipped. This spec covers **sub-project D only**: `commands/primer.md` +Step 2 item 6's "Derive from that output" list — the placeholder +gather-and-regex work that runs once per repo, during Init mode. + +## Problem + +Step 2 item 6 gathers ~9 raw facts in one Bash call (already scripted: `pwd`, +package-manifest greps, `git log --oneline -5`, an `@module` grep, a +discovered-and-run test command), then leaves the model to mentally derive +seven placeholder values from that output. Two of the seven are genuinely +judgment calls the design's parent spec +(`meta/superpowers/specs/2026-09-02-determinism-program-design.md`, "What +stays model work") already names and excludes: `{{WORKFLOW_CONVENTIONS}}`'s +draft (quoting arbitrary `CLAUDE.md` prose under a sub-heading) and +`{{REPO_LAYOUT_SUMMARY}}`'s one inferred sentence (describing a project from +file extensions present). This spec does not touch either. + +A third, `{{MODULES_TABLE}}`, looks mechanical (grep already found the +matches) but isn't: "Purpose = the `@module` value plus the docblock's +one-line description **if present**, Notes = the adjacent `Exports:` line +**if present**" depends on a JSDoc convention that varies per project — how +many lines separate the match from a description, whether an `Exports:` line +exists at all, whether the block spans one line or three. Regex-parsing this +generically is the same class of "arbitrary project prose inference" that +already got `REPO_LAYOUT_SUMMARY` and `WORKFLOW_CONVENTIONS` excluded, so it +stays prose here for the same reason, tracked as part of remaining scope (see +"Non-goals" below — it is not folded into sub-project E, which is Step 3/3b's +unrelated section-bucketing work; it simply stays put in Step 2 as-is). + +The four that remain are pure, format-fixed regex/parse operations, each +already precedented by a shipped script: + +- `{{PROJECT_NAME}}` — first non-empty of `package.json` `name`, `Cargo.toml` + `name`, `pyproject.toml` `name`, else the directory basename. Pure string + extraction, no project-specific variance. +- `{{LATEST_COMMIT_HASH_N}}` / `{{LATEST_COMMIT_SUBJECT_N}}` (N = 1..5) — + `git log --oneline -5`'s fixed `<hash> <subject>` shape. +- `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}` — the `pwd` output, verbatim. +- `{{TEST_COMMAND_SUMMARY}}` — a count-recognition regex over the one + captured test run's output. `hooks/lib/test-count-rerun.sh` (shipped, + sub-project B) already treats "`[0-9]+ pass(ed)?` found in arbitrary test + output" as a mechanical, non-judgment operation for its rerun job, which + faces the identical arbitrary-test-framework-output problem. This spec + reuses that exact regex rather than inventing a second one for the same + concept. + +## Architecture + +``` +commands/primer.md's existing primer-init-derive.sh (I/O) +Bash block (UNCHANGED) - pwd, dirname + - pwd, dirname - package.json/Cargo.toml/ + - manifest name-line greps pyproject.toml name lines + - git log --oneline -5 - git log --oneline -5 (redone + - @module grep locally — cheap, no side + - discovers + runs TEST_CMD effects, and this block never + (this is the ONE place the captured its own manifest/ + test suite actually runs) git-log output into named + - exports TEST_CMD, TEST_OUTPUT --> vars, so the script must + (already-computed, not re-run) re-read those two — but + TEST_CMD/TEST_OUTPUT it DOES + read from the environment, + never re-executes them) + - passes raw text as --arg strings + to primer-init-derive.jq +``` + +``` +primer-init-derive.jq (pure decision) + - pick PROJECT_NAME by priority + - split git log lines into HASH_N/SUBJECT_N pairs (1..5, fewer if the + repo has fewer commits — every raw line maps to exactly one pair, + parseable or not, see "Commit-line parsing" below) + - regex-match pass/fail counts out of $test_output (supplied, not + fetched) + - format TEST_COMMAND_SUMMARY, falling back to the bare command or TBD + per the rules below — never inventing a count + - emit KEY=value facts +``` + +`primer-init-derive.sh` never derives a placeholder value itself — it is a +thin I/O shim, identical in spirit to `primer-detect.sh` and +`test-count-rerun.sh`. All parsing lives in the `.jq` filter, fixture-testable +with synthetic JSON/string args, no git or subprocess required. + +**Test command: read, never re-run.** `commands/primer.md`'s existing Bash +block already discovers `TEST_CMD` and runs it exactly once (today's prose, +unchanged in shape). An earlier draft of this spec had +`primer-init-derive.sh` independently re-discover *and re-run* `TEST_CMD` — +caught in review before implementation: Init mode would have executed the +project's real test suite twice per invocation, for no benefit, purely +because the script wasn't wired to the value the surrounding block already +computed in the same shell. The fix: that Bash block adds one line, +`export TEST_CMD TEST_OUTPUT`, right after computing them (both already +exist as plain bash variables at that point — `TEST_CMD` always set, +possibly empty; `TEST_OUTPUT` set only when `TEST_CMD` was non-empty). +`primer-init-derive.sh` reads `"${TEST_CMD:-}"` / `"${TEST_OUTPUT:-}"` from +its inherited environment instead of discovering or executing anything test- +related itself. `TEST_EXIT` is not threaded through: the derivation only +ever looks for a parseable count in `$test_output`, regardless of exit code +— the same "never inspect the exit code, only the parsed output" choice +`test-count-rerun.sh`'s `run_once()` already made, so a timed-out or +nonzero-exit run degrades to the same "no parseable count" outcome as a +zero-exit run that simply printed none, with one code path for both. + +**Unchanged from today's prompt:** the raw-fact-gathering Bash block itself +(manifest checks, `git log`, the `@module` grep, test-command discovery and +execution) — this spec only replaces the *derivation* step that reads that +output, not the gathering, and reads (never re-runs) the one test execution +that block already performs. `{{MODULES_TABLE}}`, `{{REPO_LAYOUT_SUMMARY}}`, +and `{{WORKFLOW_CONVENTIONS}}` stay exactly as today's prose describes them. + +## Output contract + +`primer-init-derive.sh <project-dir>` prints, always to stdout on success: + +``` +PROJECT_NAME=<string> +WORKING_DIRECTORY_ABSOLUTE_PATH=<string> +COMMIT_COUNT=<0-5> +LATEST_COMMIT_HASH_1=<string, empty if COMMIT_COUNT<1> +LATEST_COMMIT_SUBJECT_1=<string, empty if COMMIT_COUNT<1> +LATEST_COMMIT_HASH_2=... +LATEST_COMMIT_SUBJECT_2=... +LATEST_COMMIT_HASH_3=... +LATEST_COMMIT_SUBJECT_3=... +LATEST_COMMIT_HASH_4=... +LATEST_COMMIT_SUBJECT_4=... +LATEST_COMMIT_HASH_5=... +LATEST_COMMIT_SUBJECT_5=... +TEST_CMD=<string, empty if none discovered> +TEST_COMMAND_SUMMARY=<string, see rules below — never empty> +``` + +`COMMIT_COUNT` exists because a fresh repo (Init mode's most common case — +Step 2 only runs once per repo, and often on the very first commit) can have +fewer than 5 commits; the placeholder-fill step in `commands/primer.md` uses +it to know how many `LATEST_COMMIT_*_N` placeholders the template actually +has to fill, and to leave the rest untouched rather than writing empty +`{{LATEST_COMMIT_HASH_N}}` pairs the template doesn't have anyway. Verified, +not assumed: `skills/session-continuity/templates/SESSION_PRIMER.md:27-31` +has exactly five `{{LATEST_COMMIT_HASH_N}} {{LATEST_COMMIT_SUBJECT_N}}` +lines, `N` = 1 through 5 — so `COMMIT_COUNT` never exceeds 5 by +construction, since the gathering step only ever ran `git log --oneline -5`. + +**`PROJECT_NAME` priority:** `package.json` `name` → `Cargo.toml` `name` → +`pyproject.toml` `name` → directory basename. First match wins; this ports +the existing prose's implicit ordering (the bash block checks manifests in +that order) without behavior change. + +**Commit-line parsing — every raw line yields exactly one pair.** Each +non-empty `git log --oneline -5` line is expected to match +`^\S+\s+.*$` (hash, whitespace, subject — subject may be empty). A line +that doesn't match this shape must still produce one `commits[]` entry +(hash-only, empty subject) rather than being silently dropped: jq's +`capture(re)` with no named-capture match produces *zero* outputs, not an +error and not `null` (confirmed: `jq -n '"onetoken" | capture("^(?<hash>\\S+)\\s+(?<subject>.*)$")'` +exits 0 and prints nothing), so a naive `map(capture(...))` drops any +non-matching line from the array — shrinking `COMMIT_COUNT` by one *and* +shifting every following commit's `_N` index to the wrong recency position, +silently. The filter must guard every line with `test(...)` before +`capture(...)` and fall back to a hash-only entry on no match, so +`$commits`'s length always equals the number of non-empty raw lines. + +**`TEST_COMMAND_SUMMARY` rules** (never invents a count): + +- `TEST_CMD` empty (no test command discovered) → `TBD`. +- `TEST_CMD` non-empty but the run timed out, crashed, or the captured + output has no `[0-9]+ pass(ed)?` match → the bare `` `<TEST_CMD>` `` string + (backtick-quoted, no counts). +- A pass count is found **and** a `[0-9]+ fail(ed)?` match is also found → + `` `<TEST_CMD>` — N pass / M fail ``. +- A pass count is found but no fail count is found → the bare + `` `<TEST_CMD>` `` string, same as the no-count case. This is the + conservative reading of "never invent a count": a fail count of `0` is + still a count this run did not actually report finding, since a framework + that omits a fail figure entirely (rather than printing "0 failed") gives + no positive evidence either way. + +Both count regexes are lifted verbatim from +`hooks/lib/test-count-rerun.sh`'s `run_once()`: `grep -oE '[0-9]+ pass(ed)?' | +head -1 | grep -oE '^[0-9]+'`, with `fail` substituted for the second. + +**`TEST_CMD`/`test_output` are inputs, not discovered here.** +`primer-init-derive.sh` reads `TEST_CMD` and `TEST_OUTPUT` from its +inherited environment — set by `commands/primer.md`'s existing Bash block, +which already ran the discovered command once — rather than re-discovering +or re-running a test command itself. See "Test command: read, never re-run" +above. `TEST_CMD` empty in the environment (no command was discovered or +none exists) is what drives the `TBD` case below; it is never re-derived +from the manifest inside this script. + +**Error handling**, matching `primer-detect.sh`'s precedent: jq missing, the +`.jq` filter missing or from a different `CONTRACT_VERSION`, or +`<project-dir>` not a readable directory each print one diagnostic line to +stderr and exit nonzero with no `PROJECT_NAME=` line on stdout at all. Unlike +`primer-detect.sh`'s dispatch (which gates destructive migrations), a wrong +guess here only means a template placeholder — `commands/primer.md` falls +back to asking the user for that field manually rather than inventing one, so +this is a lower-stakes failure mode, but still: no fabricated derivation on +an operational failure. + +## Testing + +Fixture-driven `.jq` tests against synthetic string args (no real git or +subprocess), mirroring `meta/superpowers/validation/2026-09-08-primer-detect-smoke.zsh`'s +format, plus `.sh` integration fixtures against scratch git repos for the +manifest-priority and commit-count-below-5 cases, plus operational-failure +cases. Matrix: + +1. `package.json` name present → `PROJECT_NAME` from it, even if `Cargo.toml` + also present (priority order). +2. Only `Cargo.toml` present → `PROJECT_NAME` from it. +3. Only `pyproject.toml` present → `PROJECT_NAME` from it. +4. No manifest → `PROJECT_NAME` = directory basename. +5. 5 commits in git log → `COMMIT_COUNT=5`, all 5 hash/subject pairs filled. +6. 2 commits (fresh repo) → `COMMIT_COUNT=2`, pairs 3-5 empty. +7. 0 commits (literally empty repo, no commits yet) → `COMMIT_COUNT=0`, all + pairs empty. +8. `TEST_CMD` empty (unset or empty in the environment) → + `TEST_COMMAND_SUMMARY=TBD`. +9. `TEST_CMD`/`TEST_OUTPUT` set as environment inputs, `TEST_OUTPUT` + contains "12 passed, 0 failed" → full `N pass / M fail` summary. +10. `TEST_CMD` set, `TEST_OUTPUT` contains "12 pass" only (no fail count) → + bare `` `<TEST_CMD>` `` string, no invented `0 fail`. +11. `TEST_CMD` set, `TEST_OUTPUT` empty or has no recognizable count → bare + `` `<TEST_CMD>` `` string. +12. A git-log line that doesn't match `<hash> <subject>` shape still yields + one `commits[]` entry (hash-only) — `COMMIT_COUNT` and every following + index stay correct, nothing silently dropped. +13. Missing `.jq` filter → nonzero exit, no `PROJECT_NAME=` line. +14. Wrong `CONTRACT_VERSION` → nonzero exit, no `PROJECT_NAME=` line. +15. `jq` absent from `PATH` → nonzero exit, no `PROJECT_NAME=` line. + +## Non-goals + +- `{{MODULES_TABLE}}`'s docblock parsing, `{{REPO_LAYOUT_SUMMARY}}`'s + inferred sentence, and `{{WORKFLOW_CONVENTIONS}}`'s draft — all three stay + prose, per the reasoning in "Problem" above and the parent program design's + "What stays model work" list. Not deferred to a later sub-project; they are + scoped out of Phase 6 entirely. +- Step 2's file-creation and template-copy steps (items 1-5), the + interactive-question step (item 7), the GitHub Issues backlog-filing block, + and the `{{...}}` residual-placeholder check (item 8) — untouched by this + spec. +- Sub-projects C (Step 3c/3d migration mechanics) and E (Step 3/3b + section-bucketing) — separate, unstarted scope. diff --git a/meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh b/meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh new file mode 100755 index 0000000..6f18e02 --- /dev/null +++ b/meta/superpowers/validation/2026-09-09-primer-init-derive-smoke.zsh @@ -0,0 +1,202 @@ +#!/usr/bin/env zsh +# primer-init-derive.sh/.jq smoke test. Two layers: +# Part A: .jq fixtures via synthetic string args (no git, no subprocess) -- +# the manifest-priority pick, git-log split, count-regex matrix. +# Part B: .sh integration fixtures via scratch git repos with real +# manifests and a fake TEST_CMD -- gathering + end-to-end wiring. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +lib="$repo/hooks/lib" +jq_filter="$lib/primer-init-derive.jq" +tool="$lib/primer-init-derive.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +# --------------------------------------------------------------------------- +# Part A: .jq fixtures +# --------------------------------------------------------------------------- + +# jq_run <pkg_name> <cargo_name> <pyproject_name> <dirname> <git_log> <test_cmd> <test_output> +jq_run() { + jq -r -n \ + --arg pkg_name "$1" --arg cargo_name "$2" --arg pyproject_name "$3" \ + --arg dirname "$4" --arg pwd "/tmp/$4" --arg git_log "$5" \ + --arg test_cmd "$6" --arg test_output "$7" \ + -f "$jq_filter" +} +jq_field() { # <output> <KEY> -> value + print -r -- "$1" | awk -F= -v k="$2" '$1==k{print substr($0, length(k)+2)}' +} + +# A1: package.json name wins over Cargo.toml even when both present +out="$(jq_run pkgname cratename "" dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "pkgname" ]] \ + && ok "A1: package.json name wins priority" || bad "A1: got '$out'" + +# A2: only Cargo.toml present +out="$(jq_run "" cratename "" dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "cratename" ]] \ + && ok "A2: Cargo.toml name used when package.json absent" || bad "A2: got '$out'" + +# A3: only pyproject.toml present +out="$(jq_run "" "" pyname dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "pyname" ]] \ + && ok "A3: pyproject.toml name used when others absent" || bad "A3: got '$out'" + +# A4: no manifest -> directory basename fallback +out="$(jq_run "" "" "" dirfallback "" "" "")" +[[ "$(jq_field "$out" PROJECT_NAME)" == "dirfallback" ]] \ + && ok "A4: directory basename fallback" || bad "A4: got '$out'" + +# A5: 5-line git log -> COMMIT_COUNT=5, all pairs filled +gitlog5=$'aaa1111 first commit\nbbb2222 second commit\nccc3333 third\nddd4444 fourth\neee5555 fifth' +out="$(jq_run pkg "" "" dir "$gitlog5" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "5" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_1)" == "aaa1111" \ + && "$(jq_field "$out" LATEST_COMMIT_SUBJECT_1)" == "first commit" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_5)" == "eee5555" ]] \ + && ok "A5: 5-commit log fully split" || bad "A5: got '$out'" + +# A6: 2-line git log (fresh repo) -> COMMIT_COUNT=2, pairs 3-5 empty +gitlog2=$'aaa1111 only commit\nbbb2222 init' +out="$(jq_run pkg "" "" dir "$gitlog2" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "2" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_3)" == "" \ + && "$(jq_field "$out" LATEST_COMMIT_SUBJECT_5)" == "" ]] \ + && ok "A6: 2-commit log leaves 3-5 empty" || bad "A6: got '$out'" + +# A7: empty git log (no commits yet) -> COMMIT_COUNT=0, all empty +out="$(jq_run pkg "" "" dir "" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "0" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_1)" == "" ]] \ + && ok "A7: empty git log -> COMMIT_COUNT=0" || bad "A7: got '$out'" + +# A8: empty TEST_CMD -> TBD +out="$(jq_run pkg "" "" dir "" "" "")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == "TBD" ]] \ + && ok "A8: no test command -> TBD" || bad "A8: got '$out'" + +# A9: pass + fail both parseable -> full summary +out="$(jq_run pkg "" "" dir "" "bun test" "12 pass, 0 fail")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`bun test` — 12 pass / 0 fail' ]] \ + && ok "A9: pass+fail parseable -> full summary" || bad "A9: got '$out'" + +# A10: pass parseable, fail not -> bare command, no invented fail count +out="$(jq_run pkg "" "" dir "" "bun test" "12 pass")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`bun test`' ]] \ + && ok "A10: pass only, no fail match -> bare command" || bad "A10: got '$out'" + +# A11: no recognizable count anywhere -> bare command +out="$(jq_run pkg "" "" dir "" "bun test" "something went wrong, no counts here")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`bun test`' ]] \ + && ok "A11: no parseable count -> bare command" || bad "A11: got '$out'" + +# A12: pytest-style "N passed, M failed" phrasing +out="$(jq_run pkg "" "" dir "" "pytest" "5 passed, 1 failed in 0.42s")" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`pytest` — 5 pass / 1 fail' ]] \ + && ok "A12: pytest phrasing parses" || bad "A12: got '$out'" + +# A13: a git-log line with no whitespace at all (no parseable subject) +# still yields exactly one commits[] entry instead of being silently +# dropped by a bare map(capture(...)). +gitlog_nospace=$'aaa1111 real commit\nnospacehash' +out="$(jq_run pkg "" "" dir "$gitlog_nospace" "" "")" +[[ "$(jq_field "$out" COMMIT_COUNT)" == "2" \ + && "$(jq_field "$out" LATEST_COMMIT_HASH_2)" == "nospacehash" \ + && "$(jq_field "$out" LATEST_COMMIT_SUBJECT_2)" == "" ]] \ + && ok "A13: non-matching git-log line still yields one commits[] entry" || bad "A13: got '$out'" + +# --------------------------------------------------------------------------- +# Part B: .sh integration fixtures +# --------------------------------------------------------------------------- + +# mk_repo <dir> [package.json contents] +mk_repo() { + local dir="$1" + rm -rf "$dir"; mkdir -p "$dir" + git -C "$dir" init -q + git -C "$dir" config user.email test@example.com + git -C "$dir" config user.name Test + print -r -- "init" > "$dir/README.md" + git -C "$dir" add -A; git -C "$dir" commit -qm "init commit" + print -r -- "second" >> "$dir/README.md" + git -C "$dir" add -A; git -C "$dir" commit -qm "second commit" +} + +# B1: package.json present -> PROJECT_NAME from it, real git log split +d="$work/b1"; mk_repo "$d" +print -r -- '{"name": "real-pkg-name"}' > "$d/package.json" +git -C "$d" add -A; git -C "$d" commit -qm "add package.json" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" PROJECT_NAME)" == "real-pkg-name" \ + && "$(jq_field "$out" COMMIT_COUNT)" == "3" ]] \ + && ok "B1: real package.json + git log wired end to end" || bad "B1: got '$out'" + +# B2: no manifest -> directory basename fallback +d="$work/b2-namedrepo"; mk_repo "$d" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" PROJECT_NAME)" == "b2-namedrepo" ]] \ + && ok "B2: no manifest -> real directory basename" || bad "B2: got '$out'" + +# B3: WORKING_DIRECTORY_ABSOLUTE_PATH matches the real path +d="$work/b3"; mk_repo "$d" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" WORKING_DIRECTORY_ABSOLUTE_PATH)" == "$d" ]] \ + && ok "B3: WORKING_DIRECTORY_ABSOLUTE_PATH is the real path" || bad "B3: got '$out'" + +# B4: TEST_CMD/TEST_OUTPUT come from the environment, not from a real run -- +# the tool must never itself execute a test command, so a TEST_CMD naming a +# script that (if actually run) would fail the whole smoke test is a +# deliberate canary: if the tool ever re-introduces its own execution, this +# assertion starts failing loudly instead of just timing out quietly. +d="$work/b4"; mk_repo "$d" +out="$(cd "$d" && TEST_CMD='exit 1; echo THIS_MUST_NEVER_RUN' TEST_OUTPUT='7 passed, 1 failed' bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" TEST_CMD)" == 'exit 1; echo THIS_MUST_NEVER_RUN' \ + && "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == '`exit 1; echo THIS_MUST_NEVER_RUN` — 7 pass / 1 fail' ]] \ + && ok "B4: TEST_CMD/TEST_OUTPUT read from env, never executed" || bad "B4: got '$out'" + +# B5: no TEST_CMD in the environment -> TBD, same as the no-manifest case +d="$work/b5"; mk_repo "$d" +out="$(cd "$d" && bash "$tool" "$d" 2>&1)" +[[ "$(jq_field "$out" TEST_COMMAND_SUMMARY)" == "TBD" ]] \ + && ok "B5: no TEST_CMD in environment -> TBD" || bad "B5: got '$out'" + +# --------------------------------------------------------------------------- +# Operational failure cases +# --------------------------------------------------------------------------- + +# B6: missing .jq filter +d="$work/b6"; mk_repo "$d" +badlib="$work/badlib"; mkdir -p "$badlib"; cp "$tool" "$badlib/" +out="$(cd "$d" && bash "$badlib/primer-init-derive.sh" "$d" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"PROJECT_NAME="* ]] \ + && ok "B6: missing filter -> nonzero exit, no PROJECT_NAME= line" || bad "B6: rc=$rc out='$out'" + +# B7: wrong CONTRACT_VERSION +d="$work/b7"; mk_repo "$d" +wronglib="$work/wronglib"; mkdir -p "$wronglib"; cp "$tool" "$wronglib/" +sed 's/CONTRACT_VERSION=1/CONTRACT_VERSION=99/' "$jq_filter" > "$wronglib/primer-init-derive.jq" +out="$(cd "$d" && bash "$wronglib/primer-init-derive.sh" "$d" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"PROJECT_NAME="* ]] \ + && ok "B7: wrong CONTRACT_VERSION -> nonzero exit, no PROJECT_NAME= line" || bad "B7: rc=$rc out='$out'" + +# B8: jq absent from PATH +d="$work/b8"; mk_repo "$d" +nojq="$work/nojq"; mkdir -p "$nojq/bin" +for b in bash git awk grep sed head cat mktemp dirname timeout wc tr; do + p="$(command -v "$b")"; [[ -n "$p" ]] && ln -sf "$p" "$nojq/bin/$b" +done +out="$(cd "$d" && PATH="$nojq/bin" bash "$tool" "$d" 2>&1)"; rc=$? +[[ "$rc" -ne 0 && "$out" != *"PROJECT_NAME="* ]] \ + && ok "B8: jq absent from PATH -> nonzero exit, no PROJECT_NAME= line" || bad "B8: rc=$rc out='$out'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) From ff904fbe3b8ef691e77ba622b322a3e852f941a3 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Wed, 9 Sep 2026 11:42:23 -0700 Subject: [PATCH 16/20] docs: deprioritize Phase 6 sub-project C, file format-mismatch follow-up No real audience today (this repo's own BACKLOG.md is gone, no other plugin installs known to exist) makes scripting the git mv/git rm migration mechanics speculative work. Filed #59 to track the finding and the 3b/3d heading-format mismatch discovered while scoping it. --- .../2026-09-02-determinism-program-design.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index 16cfabf..c9ce95b 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -219,11 +219,20 @@ shipped** — Step 2's placeholder derivation (`{{PROJECT_NAME}}`, commit hash/subject pairs, `{{TEST_COMMAND_SUMMARY}}`), now `hooks/lib/primer-init-derive.sh`/`.jq`. Spec: `meta/superpowers/specs/2026-09-09-primer-init-derive-design.md`. Plan: -`meta/superpowers/plans/2026-09-09-primer-init-derive.md`. Still pending: -C (Step 3c/3d's `git mv`/`git rm` migration mechanics themselves — -sub-project A only scripted *whether* they run, not *what* they do) and E -(Step 3/3b's section-bucketing judgment, lowest priority — near-zero -remaining audience, most judgment-heavy of the five). +`meta/superpowers/plans/2026-09-09-primer-init-derive.md`. **Sub-project C +deprioritized, not scoped** — Step 3c/3d's `git mv`/`git rm` migration +mechanics (sub-project A only scripted *whether* they run, not *what* they +do) have zero real audience today: this repo's own `BACKLOG.md` is already +gone, and to the maintainer's knowledge no other installs of this plugin +exist yet (no marketplace submission — `#35`). The step only matters for a +project on a pre-v0.29 install that hasn't run `/session-continuity:primer` +since, a population that's currently empty. Scoping it now would be +speculative work for a hypothetical future user, not a real one — see +`#59`, which also documents a real format mismatch found while scoping this +(Step 3b's `OUTSTANDING_ITEMS.md` headings carry no hex tag/date; Step 3d's +`BACKLOG.md` parser assumes both are present) to fix whenever this is +revisited. Still pending: E (Step 3/3b's section-bucketing judgment, lowest +priority — near-zero remaining audience, most judgment-heavy of the five). **Phase 7 `#44` — the gate that keeps it true.** A commit-time content gate on staged `commands/*.md` that blocks prompt text instructing a model to count, From 8a677cceab0610e18aead9d6c0fdc7a245522e7b Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Wed, 9 Sep 2026 11:45:07 -0700 Subject: [PATCH 17/20] docs: deprioritize Phase 6 sub-project E, same reasoning as C Same audience argument as #59: Step 3/3b's split-mode migrations are legacy-only and this plugin has no external installs yet. Phase 6 is done for now -- A, B, D shipped; C, E parked pending #35. --- .../specs/2026-09-02-determinism-program-design.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index c9ce95b..df9067d 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -231,8 +231,13 @@ speculative work for a hypothetical future user, not a real one — see `#59`, which also documents a real format mismatch found while scoping this (Step 3b's `OUTSTANDING_ITEMS.md` headings carry no hex tag/date; Step 3d's `BACKLOG.md` parser assumes both are present) to fix whenever this is -revisited. Still pending: E (Step 3/3b's section-bucketing judgment, lowest -priority — near-zero remaining audience, most judgment-heavy of the five). +revisited. **Sub-project E deprioritized, not scoped, same reasoning** — +Step 3/3b's section-bucketing (pre-v0.13/v0.22 split-mode migrations) is the +same category as C: legacy-migration-only, zero real audience today, and +the most judgment-heavy of the five besides. Phase 6 is done for now: A, B, +and D shipped; C and E stay parked until this plugin actually has external +installs old enough to hit either path (tracked via `#35`, not reopened +here speculatively). **Phase 7 `#44` — the gate that keeps it true.** A commit-time content gate on staged `commands/*.md` that blocks prompt text instructing a model to count, From 79233c92401b813fd3279587e417bcf3f36c6434 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Wed, 9 Sep 2026 11:48:31 -0700 Subject: [PATCH 18/20] fix: bump count-entries-smoke.zsh's real-LEARNINGS.md pin (16 -> 20) Fixes #56. --- .../superpowers/validation/2026-09-02-count-entries-smoke.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh b/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh index 5ce7c8e..9d4fba0 100755 --- a/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh +++ b/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh @@ -37,8 +37,8 @@ work="$(mktemp -d)" # against `grep -cE '^### [0-9]+\.'` directly (the naive expression is # correct here precisely because no real entry heading sits inside a # comment or a fence — that only happens in the shipped templates below). -# Pin last bumped 2026-09-07 (15 -> 16, one more entry landed since). -assert_count "real LEARNINGS.md" "$repo/.session-continuity/LEARNINGS.md" 16 +# Pin last bumped 2026-09-09 (16 -> 20, four more entries landed since). +assert_count "real LEARNINGS.md" "$repo/.session-continuity/LEARNINGS.md" 20 # count-entries.sh is file-format agnostic (LEARNINGS still uses it). A # synthetic markdown file pins the heading-count contract without depending From 8c44a15c936a5b9c23014a4ae1e001f49009e2ad Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Wed, 9 Sep 2026 14:03:43 -0700 Subject: [PATCH 19/20] Determinism Phase 7: derived-value-gate.sh, closes #44 (and #54) (#61) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: Determinism Phase 7 plan (derived-value-gate), fixes #54 first Plan for closing #44 with hooks/derived-value-gate.sh, a seventh commit-time content gate covering count/tally, duration, compare-claimed-vs-actual, and print-verbatim instruction classes. Renumber dropped from v1 (no grounded removal to anchor it on). Sequences a fix for #54 (end-session.md's unmigrated majority-vote rerun) ahead of wiring the gate, since the gate's own count pattern would otherwise deny it on sight. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs: LEARNINGS #21, nested-heredoc git commit -m triggers spurious gate denials Three real commit attempts each denied on a different content gate against unchanged, correctly-escaped staged content; direct re-runs of each denying gate against the same blob always allowed. Workaround confirmed: `git commit -F-` with a plain heredoc, first try. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: end-session.md's drift check now calls test-count-rerun.sh (closes #54) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat: add derived-value-gate.sh, the Phase 7 commit-time content gate Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: correct count-check pattern to match grounded citation The pattern `Pin.*across[[:space:]]+[0-9]+[[:space:]]+runs` did not match the grounded citation from the plan ("saw 1162 / 1161 / 1162 across 3 runs — using 1162; suite is unstable") because that string contains no word "Pin" on the same line. Since grep -E never spans lines, this alternative was unreachable dead code disconnected from its citation—a Global Constraint violation. Replace with `saw.*across[[:space:]]+[0-9]+[[:space:]]+runs[[:space:]]*—` which anchors on the distinctive em-dash present only in the actual report format, not in template documentation strings. Verified: - Matches grounded citation: "saw 1162 / 1161 / 1162 across 3 runs — using 1162" - No match on end-session.md documentation: "saw <OBSERVED> across 3 runs." Smoke test: pass=9 fail=0 ✓ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat: wire derived-value-gate.sh into hooks.json Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs: Phase 7 doc pointers, SECURITY.md correction, changelog, and version bump Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * test: cover derived-value-gate.sh, bump LEARNINGS.md count pin (20 -> 21) hook-json-contract-smoke.zsh's completeness check had no fixture for the new gate; count-entries-smoke.zsh's real-file pin was stale after adding LEARNINGS #21. Full validation suite now matches main's exact baseline (candidate-replay.zsh, learnings-index-smoke.zsh, render-smoke.zsh remain pre-existing failures, unrelated to this branch, confirmed by running the same suites against a clean main worktree). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --- .claude-plugin/plugin.json | 2 +- .session-continuity/LEARNINGS.md | 42 ++ CHANGELOG.md | 17 + SECURITY.md | 8 +- commands/end-session.md | 73 +- hooks/derived-value-gate.sh | 90 +++ hooks/hooks.json | 1 + ...-determinism-phase-7-derived-value-gate.md | 659 ++++++++++++++++++ .../2026-09-02-determinism-program-design.md | 14 +- .../2026-08-12-hook-json-contract-smoke.zsh | 4 +- .../2026-09-02-count-entries-smoke.zsh | 4 +- .../2026-09-09-derived-value-gate-smoke.zsh | 75 ++ 12 files changed, 949 insertions(+), 40 deletions(-) create mode 100755 hooks/derived-value-gate.sh create mode 100644 meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md create mode 100644 meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 635cd72..91f358c 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session-continuity", - "version": "0.34.0", + "version": "0.35.0", "description": "Cross-session memory for Claude Code projects via four in-repo docs: SESSION_PRIMER.md (current state), PROJECT_CONTEXT.md (stable repo context), ROADMAP.md (strategic direction), and LEARNINGS.md (hard-won bugs), plus GitHub Issues labeled backlog for the work queue.", "author": { "name": "Tal Golan" diff --git a/.session-continuity/LEARNINGS.md b/.session-continuity/LEARNINGS.md index 93519a1..53f1dee 100644 --- a/.session-continuity/LEARNINGS.md +++ b/.session-continuity/LEARNINGS.md @@ -35,6 +35,7 @@ within each group. - The `/session-continuity:end-session` smoke test had two staged files (primer + `src/foo.js`). The… — #3 - The smoke test written for exactly this case (`Smoke: N/A deferred, this… — #16 - This repo moved everything to `meta/superpowers/` in v0.3 (per CHANGELOG: "Repo layout:… — #5 +- Three consecutive real `git commit` attempts with that nested — #21 - Three hermetic smoke suites under `meta/superpowers/validation/` had fixtures hardcoded to the exact… — #9 --- @@ -234,6 +235,47 @@ Applies generally: any time command prose tells Claude to produce an inventory f ## Hook scripting (SessionStart / PreToolUse) +### 21. `git commit -m "$(cat <<'EOF' ... EOF)"` triggers spurious content-gate denials that a direct script re-test can't reproduce +Slug: nested-heredoc-commit-msg-gate-misfire +Trigger: Bash /git commit -m "\$\(cat/ + +**The trap.** Committing a file with valid, correctly-formatted escape-hatch +lines (`Proven-gate: N/A — ...`, `Evidence-gate: N/A — ...`, +`Backend-parity: N/A — ...`) via `git commit -m "$(cat <<'EOF' ... EOF)"` — +natural for a multi-line, well-formatted commit message — looks like it +should pass the exact same commit-time content gates that a plain `git +commit -m "one line"` would. + +**Symptom.** Three consecutive real `git commit` attempts with that nested +heredoc form each denied, quoting a *different* gate's message each time +(`Evidence-gate` once, `Backend-parity-gate` twice) — same staged content, +same escape hatches present throughout. Re-running each denying gate script +directly against the identical staged blob (`git show ":path" | bash +hooks/<gate>.sh`, or via a payload file redirected on stdin, `bash +hooks/<gate>.sh < payload.json`) always returned a clean allow — the gate +logic itself was never the problem. Switching to `git commit -F-` with a +plain (non-command-substitution) heredoc succeeded immediately, first try, +no other change. + +**Fix.** When a `git commit -m "$(cat <<...)"` denial's cited line/match +can't be reproduced by feeding the same staged content directly to the +named gate script, don't iterate on the gate's regex or escape-hatch +wording — the mismatch is downstream of the gate. Use `git commit -F-` +with a plain heredoc (`git commit -F- <<'EOF' ... EOF`) instead; it passes +the message on stdin rather than as a shell-substituted `-m` argument, and +side-steps whatever in the nested `$(...)` form's re-encoding is producing +an inconsistent view of the staged content across separate hook +invocations. The exact mechanism (payload JSON construction for a complex +multi-line `-m` argument, most likely) was not confirmed — only the trigger +condition and the workaround. + +**Diagnostic signal.** A commit denial that cites a *different* gate on +each retry against unchanged staged content — not the same gate every +time — is the tell that the gates aren't the problem; the commit +invocation's own argument-passing shape is. + +--- + ### 16. Masking a gate's own escape hatch must cover every raw-`$content` check in that gate, not just the one the bug report named Slug: gate-mask-partial-migration Trigger: Edit /-gate\.sh$/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 12fea48..70f4644 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.35.0] — 2026-09-09 + +### Added +- **A seventh commit-time content gate, `hooks/derived-value-gate.sh`.** + Blocks new `commands/*.md` prompt text that instructs a model to compute a + duration by hand, tally/vote on a count by eye, eyeball-compare a claimed + value against an actual one, or print fixed reference text as if it were + an instruction — the reconciler-level enforcement of the determinism + program's invariant (every other phase is a one-time cleanup that decays + without this). Escape hatch: `Derived-value-gate: N/A — <reason>`. + +### Fixed +- **`end-session.md`'s drift check now calls `test-count-rerun.sh`** instead + of hand-deriving the same majority-vote rerun Phase 6-B already scripted + for `primer.md` — the two command files were computing the identical + algorithm two different ways. + ## [0.34.0] — 2026-09-09 ### Changed diff --git a/SECURITY.md b/SECURITY.md index 3caaf66..a86e9da 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -36,7 +36,7 @@ A reasonable response should arrive within a week. If you haven't heard back aft - **Hooks read stdin JSON, not env vars.** Claude Code delivers hook payloads as stdin; the hooks extract `cwd` and `tool_input.command` from that JSON using `grep`/`sed`. These values are only used as test operands (`[ -d ]`, `[ -f ]`), as an argument to `git -C`, or matched against a `case` glob pattern — never `eval`ed or interpolated into a shell string that gets executed. Failure modes on malformed input are a silent `exit 0`. - **Network call.** `hooks/version-check.sh` makes one unauthenticated `HEAD`-style GET per week per machine to the public GitHub Releases API, with a 3-second timeout, silent failure, and an opt-out env var (`SESSION_CONTINUITY_SKIP_UPDATE_CHECK=1`). No analytics, no identifiers, no PII. The cache key is stored at `${XDG_CACHE_HOME:-$HOME/.cache}/session-continuity/last-check`. - **Release workflow input validation.** `.github/workflows/release.yml` reads the tag name from `GITHUB_REF_NAME`, strips the leading `v`, and validates the result against a strict semver regex before feeding it to `awk`. Additional belt-and-suspenders: the `awk` pattern uses `index()` (string-literal match) rather than regex (`~`), so unusual characters in the tag name can never become pattern metacharacters. -- **Hook matcher scope.** `hooks/hooks.json` registers one `SessionStart` hook and seven `PreToolUse` hooks, split across two matcher groups: - - `matcher: "Bash"` — `pre-commit-check.sh` and `flaky-gate.sh`'s commit-message check both carry a per-hook `if: Bash(git commit *)` filter, so they only spawn on `git commit`. `learnings-surface.sh` has no `if` filter in this group — it spawns on every `Bash` call, not just commits, since its job is to match the imminent command text against LEARNINGS trigger regexes. - - `matcher: "Write|Edit"` — `learnings-surface.sh`, `smoke-gate.sh`, `proven-gate.sh`, `occurrence-gate.sh`, `evidence-gate.sh`, `flaky-gate.sh`, and `backend-parity-gate.sh` all spawn on every `Write`/`Edit` call. Each self-scopes internally (by file path pattern — plan files, spec files, or `LEARNINGS.md`) and exits 0 immediately for files outside its scope, so the broad matcher is narrowed in-script rather than in `hooks.json`. - - Five of these seven (`smoke-gate`, `proven-gate`, `occurrence-gate`, `evidence-gate`, `backend-parity-gate`, and `flaky-gate`'s Write/Edit path) can return `permissionDecision:"deny"` and block the tool call — the others (`session-start.sh`, `pre-commit-check.sh`, `learnings-surface.sh`) are non-blocking, `permissionDecision:"allow"` or silent-exit only. +- **Hook matcher scope.** `hooks/hooks.json` registers one `SessionStart` hook (`session-start.sh`), one `UserPromptSubmit` hook (`prompt-intercept.sh`), and ten `PreToolUse` hooks, split across two matcher groups: + - `matcher: "Bash"` — nine hooks. Eight carry a per-hook `if: Bash(git commit *)` filter (`pre-commit-check.sh`, `flaky-gate.sh`, `proven-gate.sh`, `smoke-gate.sh`, `evidence-gate.sh`, `backend-parity-gate.sh`, `occurrence-gate.sh`, `derived-value-gate.sh`) so they only spawn on `git commit`. `learnings-surface.sh` has no `if` filter — it spawns on every `Bash` call, not just commits, since its job is to match the imminent command text against LEARNINGS trigger regexes. + - `matcher: "Write|Edit"` — `learnings-surface.sh` only. + - Seven of the nine `Bash`-matcher hooks are content gates that can return `permissionDecision:"deny"` and block the tool call: `flaky-gate`, `proven-gate`, `smoke-gate`, `evidence-gate`, `backend-parity-gate`, `occurrence-gate`, and `derived-value-gate`. The rest (`pre-commit-check.sh`, `learnings-surface.sh`, `session-start.sh`, `prompt-intercept.sh`) are non-blocking, `permissionDecision:"allow"` or silent-exit only. diff --git a/commands/end-session.md b/commands/end-session.md index 60837d0..c1b0081 100644 --- a/commands/end-session.md +++ b/commands/end-session.md @@ -220,29 +220,53 @@ Read `.session-continuity/SESSION_PRIMER.md` and compare its `git log --oneline - **≥1 `appears-DONE` item.** Run the drift-clean close-candidate prompt below instead of skipping Step 1. - **Block differs** (any line differs — subjects, hashes, or ordering). Enter the refresh flow below. -If the primer has a test-counts section, decide whether to re-run it (logic -lives in Step 5.3 of `commands/primer.md` — summarized here). Do this as -**one Bash call**, timed, tracking a `RETRIES` count (0 if skipped or the -first run matched, else the number of *extra* runs actually executed -beyond the first): - -- **Skip the rerun** if the commit list already computed above - (`<last-primer-commit>..HEAD`) contains no file outside - `.session-continuity/` — no source or test file changed, so the recorded - count cannot have drifted. -- **Otherwise, run the test command(s) once.** Matches the primer's - recorded count → stop, no drift on this axis. -- **Only if that first run disagrees**, retry up to 2 more times (3 total) - to rule out flakiness. Pin to the count seen in ≥2 of 3 runs — if that - pinned count matches the primer, the first run was the flake and there's - no drift; if it still differs, report drift with the pinned count. If all - three runs disagree with each other, surface the spread (`saw 1162 / 1161 - / 1162 across 3 runs — using 1162; suite is unstable`) instead of - silently picking one. - -Common cases stay cheap: zero test runs when nothing relevant changed, one -run when the count still holds, three only when there's an actual -discrepancy to resolve. +Run the shared test-count rerun script — the same one `commands/primer.md` +Step 4 item 3 calls, so both commands stay in lockstep — timed: + +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) +source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" 1; then + RERUN_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" . "$LAST_PRIMER_COMMIT" 2>&1)" + RERUN_STATUS=$? +else + RERUN_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + RERUN_STATUS=1 +fi +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +RETRIES=$(printf '%s' "$RERUN_OUTPUT" | awk -F= '/^RETRIES=/{print $2}') +echo "$RERUN_OUTPUT" +echo "RERUN_STATUS=$RERUN_STATUS" +``` + +Run this as the **same Bash tool call** as the pre-existing perf-log block a +few lines below ("At the end of this Bash call (whichever branch above +ran):", unmodified by this task) — that block reads `$_PERF_DURATION` and +`$RETRIES` from this one. A separate tool invocation would see both empty +and silently log a wrong duration/retries. + +**If `RERUN_STATUS` is nonzero, or `$RERUN_OUTPUT` has no `MODE=` line:** +report `$RERUN_OUTPUT` to the user and fall back to `TBD` for this axis — +never fabricate a drift verdict from a failed script. + +**Otherwise**, report per `MODE`: +- `skip` — no relevant file changed; say nothing (matches today's silent + skip). +- `no-command` — no test command recorded; nothing to check. +- `no-count`, `RETRIES=0`, `DRIFT=0` always — nothing recorded yet to + compare against; no report needed on this axis. +- `run` with `DRIFT=0` — the count held (whether on the first try or after + majority-vote confirmation); no report needed. +- `run` with `DRIFT=1` — report drift using `PINNED_COUNT` (`"Test count + drifted: recorded <RECORDED_COUNT>, now <PINNED_COUNT> (confirmed over + <RETRIES>+1 runs)."`). +- `run` with `SPREAD=1` — report instability using the comma-joined + `OBSERVED` values (`"Test suite is unstable: saw <OBSERVED, /-joined> + across 3 runs."`), not a drift verdict. +- `run` with `UNPARSEABLE=1` and no `PINNED_COUNT` — report `"Test command + produced no parseable count after <RETRIES>+1 attempts."` At the end of this Bash call (whichever branch above ran): ```bash @@ -278,7 +302,8 @@ A lighter-weight alternative to the refresh flow below — no git-log regenerati Follow the logic in **Step 5 of `commands/primer.md`** (refresh mode): 1. Regenerate the `git log --oneline -5` block with current output. -2. If the primer has a test-counts section and the counts changed (after the 3× retry), update them to match current output. +2. If `MODE=run` and `DRIFT=1` (per the test-count rerun script's output + above), update the test-counts section to `PINNED_COUNT`. 3. **Surface commits since the last primer refresh, with backlog overlay.** Reuse the commit list already computed in the Backlog verification section above (`git log <last-primer-commit>..HEAD --oneline`) — do not recompute it. Present the subject list as candidate prompts. Then look up the **backlog overlay** for each subject: filter diff --git a/hooks/derived-value-gate.sh b/hooks/derived-value-gate.sh new file mode 100755 index 0000000..6e3374a --- /dev/null +++ b/hooks/derived-value-gate.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# derived-value-gate.sh — commit-time content gate (session-continuity plugin, +# Determinism Phase 7, closes #44). +# +# Fires before Bash(git commit *). For each staged commands/*.md file, BLOCKS +# prompt text instructing a model to (1) compute a duration by hand, (2) +# tally/vote on a count by eye, (3) eyeball-compare a claimed value against an +# actual one, or (4) print fixed reference text as if it were an instruction — +# the four defect classes Phases 0-6 of the determinism program removed. See +# meta/superpowers/specs/2026-09-02-determinism-program-design.md and +# meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md +# for the grounding (which real diff each pattern below is anchored to). +# +# A fifth class named in #44 — "renumber" — is deliberately NOT checked here: +# no real removed instance exists to ground a pattern on (see the plan above), +# and a naive word-anchor false-positives on learning.md's own anti-renumber +# stability guarantees. +# +# Escape: `Derived-value-gate: N/A — <reason>`. +set -euo pipefail +# shellcheck disable=SC1091 # dynamically-resolved path; gate-common.sh is shellcheck-clean standalone +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/gate-common.sh" + +# shellcheck disable=SC2329 # called indirectly by gate_scan_staged +gate_in_scope() { + case "$1" in commands/*.md) return 0 ;; *) return 1 ;; esac +} + +# Each check takes (masked-content, path) and calls deny (exits) on a hit. +# Citation format matches occurrence-gate.sh's own: grep -n gives "N:match". + +_dvg_deny() { # <path> <label> <hit "N:text"> <explanation> + local path="$1" label="$2" hit="$3" explanation="$4" line matched + line="${hit%%:*}" + matched="$(printf '%s' "${hit#*:}" | cut -c1-120)" + deny "In staged file $path, line $line: $label (\"$matched\"). $explanation Add: Derived-value-gate: N/A — <reason> (decoration fine)." +} + +_dvg_check_duration() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE 'date -u -j -f|date -u -d "|\$\(\([^)]*_epoch[^)]*-[^)]*_epoch' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "instructs a model to compute a duration by hand (epoch subtraction)" "$hit" \ + "A script owns duration math — see hooks/lib/perf-log.sh's since subcommand." +} + +_dvg_check_count() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE 'cardinality|Pin to the count seen in|RETRIES count|saw.*across[[:space:]]+[0-9]+[[:space:]]+runs[[:space:]]*—' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "instructs a model to tally or vote on a count by eye" "$hit" \ + "A script owns cardinality/majority-vote math — see hooks/lib/token-overlap.sh and hooks/lib/test-count-rerun.sh." +} + +_dvg_check_compare() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE '^[[:space:]]*[Dd]oes[^.]*match[^.]*above|match(es)?[[:space:]]+the[^.]*output above|disagrees with the recorded' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "instructs a model to eyeball-compare a claimed value against an actual one" "$hit" \ + "A script owns the comparison (an awk range extract plus diff, or the same shape as hooks/lib/primer-detect.sh)." +} + +_dvg_check_verbatim() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE 'not instructions to you|Illustrative only|List every file[^.]*do not summarize|Never omit it\. Never replace it with paraphrased prose|Always emit[^.]*exactly:' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "ships fixed reference text or a determinism-compensating instruction as prompt prose" "$hit" \ + "Fixed output belongs in the script that computes the values around it (skills/session-continuity/REFERENCE.md or a spec, not a command body)." +} + +# shellcheck disable=SC2329 # called indirectly by gate_scan_staged +gate_check() { + local content="$1" path="$2" masked + if gate_has_escape "$content" "Derived-value-gate"; then return 0; fi + masked="$(gate_mask_escape "$content" "Derived-value-gate")" + # Fixed priority order below (duration > count > compare > verbatim): a + # line tripping two categories at once is cited under the first one + # checked, not necessarily the earliest line in the file. Harmless — one + # escape hatch clears every category — but worth knowing when reading a + # denial that names a category other than the one you expected. + _dvg_check_duration "$masked" "$path" + _dvg_check_count "$masked" "$path" + _dvg_check_compare "$masked" "$path" + _dvg_check_verbatim "$masked" "$path" +} + +gate_load +gate_is_commit || exit 0 +gate_scan_staged gate_in_scope gate_check +exit 0 diff --git a/hooks/hooks.json b/hooks/hooks.json index 613a00d..3dd143d 100644 --- a/hooks/hooks.json +++ b/hooks/hooks.json @@ -17,6 +17,7 @@ { "type": "command", "if": "Bash(git commit *)", "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-wrap.sh evidence-gate.sh" }, { "type": "command", "if": "Bash(git commit *)", "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-wrap.sh backend-parity-gate.sh" }, { "type": "command", "if": "Bash(git commit *)", "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-wrap.sh occurrence-gate.sh" }, + { "type": "command", "if": "Bash(git commit *)", "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-wrap.sh derived-value-gate.sh" }, { "type": "command", "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-wrap.sh learnings-surface.sh" } ] }, diff --git a/meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md b/meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md new file mode 100644 index 0000000..57f2af1 --- /dev/null +++ b/meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md @@ -0,0 +1,659 @@ +# Determinism Phase 7 — Derived-Value Gate Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Ship a seventh commit-time content gate, `hooks/derived-value-gate.sh`, +that blocks new prompt text in `commands/*.md` instructing a model to compute a +duration, tally/vote on a count, eyeball-compare a claimed value against an +actual one, or print fixed reference text as if it were an instruction — the +reconciler-level enforcement of the determinism program's invariant. Closes +GitHub issue `#44`. Along the way, fixes `#54` (an un-migrated duplicate of +already-scripted majority-vote logic that the gate's own count pattern would +otherwise immediately flag) and corrects a stale `SECURITY.md` claim about +which gates are wired to which hook matcher. + +**Architecture:** `derived-value-gate.sh` follows the exact idiom of the six +existing gates in `hooks/*.sh` (`occurrence-gate.sh`, `proven-gate.sh`, etc.): +source `hooks/lib/gate-common.sh`, define `gate_in_scope` (staged path matches +`commands/*.md`) and `gate_check` (content + path -> `deny` on a match), then +`gate_load; gate_is_commit || exit 0; gate_scan_staged gate_in_scope +gate_check; exit 0`. `gate_check` masks this gate's own escape-hatch line +(`gate_mask_escape`, so a doc that legitimately cites the escape label doesn't +self-condemn), then runs four independent phrase-pattern checks in sequence, +each denying with a category-specific reason on first hit. Escape hatch: +`Derived-value-gate: N/A — <reason>`. + +**Pattern grounding (per the design doc's requirement that Phase 7's patterns +come from what earlier phases actually removed, not guesswork):** git history +was mined for the literal instruction phrasing Phases 0–6 deleted from +`commands/*.md`. Four categories have solid grounded hits and ship in v1: + +1. **Duration** — the four near-identical epoch-subtraction blocks Phase 3 + replaced with `perf-log.sh`: `date -u -j -f`, `date -u -d "`, and the + `$(( ..._epoch - ..._epoch` arithmetic idiom. +2. **Count/tally** — Phase 6-B's majority-vote prose: `cardinality`, `Pin to + the count seen in`, `RETRIES count`, `across <N> runs` (from the spread + report "saw 1162 / 1161 / 1162 across 3 runs"). +3. **Compare claimed-vs-actual** — Phase 6-A's eyeball-diff prose: `match(es) + the ... output above`, `disagrees with the recorded`, `does ... match ... + above`. +4. **Print-verbatim / reference-as-instruction** — Phase 2/4's fixed-text + leakage: `not instructions to you`, `Illustrative only`, `List every + file...do not summarize`, `Never omit it. Never replace it with + paraphrased prose`, `Always emit ... exactly:`. + +A fifth category from issue `#44`'s scope — **renumber** — is **dropped from +v1**. There is no real removed instance to ground it on (Phase 6 sub-projects +C/E, which would have produced one, were explicitly deprioritized rather than +shipped — see the program design doc's Phase 6 entry). Worse, a bare +`renumber(ing)?` word-anchor was checked against the current repo and hits +three real lines in `learning.md`, all of which state entries are *never* +renumbered (a stability guarantee, the opposite of a violation) — shipping it +would deny any future commit touching that file. Filed as a follow-up: this +category ships only once a real removed instance exists to anchor it on. + +**Sequencing decision:** the count/tally pattern (`Pin to the count seen in`) +also hits a live, currently-shipped line — `end-session.md`'s "Drift check" +section still hand-derives the exact majority-vote rerun that Phase 6-B +scripted into `hooks/lib/test-count-rerun.sh`/`.jq` for `primer.md` (filed as +`#54`, found during Phase 6-B's own review, explicitly out of that plan's +scope). Fixing `#54` is Task 1 of this plan, before the gate is wired in +(Task 3) — otherwise every future commit touching `end-session.md`, including +unrelated ones, would deny until someone adds an escape-hatch line. + +**Tech Stack:** bash (macOS default, no bash-4 features — matches every +existing gate), zsh for the smoke-test harness (matches +`meta/superpowers/validation/lib/gate-test-common.zsh`'s existing convention), +`git`, `grep -E`. + +**Spec:** `meta/superpowers/specs/2026-09-02-determinism-program-design.md` +(Phase 7 entry, lines 242–249; the "Six categories of avoidable work" section, +lines 64–112, is the source the mined phrases above are grounded against). No +separate Phase-7-specific spec file exists — the design was brainstormed and +approved in chat this session; the grounding detail above is the durable +record of that design, since there's nowhere else for it to live once this +plan itself points here. + +## Global Constraints + +- Every new gate check must be traceable to an actual diff (cite commit hash + + file) or explicitly labeled as ungrounded — no guessed patterns ship without + that label. (This is why `renumber` is dropped, not shipped ungrounded.) +- Escape hatch label: `Derived-value-gate: N/A — <reason>` (decoration + tolerant, per `gate_has_escape`'s existing convention — backticks/asterisks + stripped before matching). +- `gate_in_scope` matches `commands/*.md` at repo root only (the seven files: + `end-session.md`, `primer.md`, `learning.md`, `doctor.md`, `help.md`, + `spike-check.md`, `update.md`) — not nested `commands/` directories + elsewhere, matching how `occurrence-gate.sh` scopes to `.session-continuity/ + LEARNINGS.md` rather than any `LEARNINGS.md`. +- No new external dependencies. Pure `grep -E`, no `jq`, no `awk` beyond what + `gate-common.sh` already uses. +- Before wiring the gate into `hooks.json` (Task 3), the real, current content + of all seven `commands/*.md` files must pass it clean (zero denials) — the + gate ships enforcing an invariant the repo already satisfies, not one it's + about to start violating. + +--- + +**Gate escape hatches (for this document itself, not the code it +describes):** this plan names several existing gates by filename and quotes +their trigger vocabulary, which trips two of them on their own scope +(`*/plans/*.md`) purely by self-reference — the documented failure mode for +grep-based gates scanning a document about themselves (this repo's own +`LEARNINGS.md` entry 7). Per that entry's own fix, the right response is the +escape hatch, not loosening the gate: + +> **Proven-gate:** N/A — this plan names `proven-gate.sh` by filename only; +> it makes no proven/verified claim about tested work. +> **Evidence-gate:** N/A — this plan's smoke-test fixtures call the existing +> `gt_cleanup` test-teardown helper; there is no smoke run here needing +> preserve-before-teardown language. +> **Backend-parity:** N/A — this plan names `backend-parity-gate.sh` by +> filename only; it does not frame anything as multi-backend. + +--- + +## Task 1: Fix `#54` — converge `end-session.md`'s drift-check rerun onto `test-count-rerun.sh` + +**Files:** +- Modify: `commands/end-session.md:223-245` (the hand-derived retry/pin-to- + majority prose) and `commands/end-session.md:281` (the refresh flow's + reference to "after the 3× retry") + +**Interfaces:** +- Consumes: `hooks/lib/test-count-rerun.sh` (existing, unmodified — usage: + `test-count-rerun.sh <project-dir> <last-primer-commit>`, prints + `KEY=value` lines: `TEST_CMD`, `RECORDED_COUNT`, `MODE` + (`skip|no-command|no-count|run`), `RETRIES`, `OBSERVED`, `UNPARSEABLE`, + `DRIFT`, `PINNED_COUNT`, `SPREAD`), `hooks/lib/require-script.sh`'s + `require_script` function (existing, already used identically in + `commands/primer.md:309-316`). + +This task has no automated test of its own — it's a markdown prompt-text +edit, not code. Its "test" is: (a) a byte-diff confirming only the intended +lines changed, (b) confirming the file still parses as valid markdown (no +broken code fences), and (c) Task 2's gate-pattern sanity check (later in this +plan) finding zero hits in the corrected file. + +- [ ] **Step 1: Replace the hand-derived retry prose** + +In `commands/end-session.md`, find this exact block (currently lines +223–245): + +```markdown +If the primer has a test-counts section, decide whether to re-run it (logic +lives in Step 5.3 of `commands/primer.md` — summarized here). Do this as +**one Bash call**, timed, tracking a `RETRIES` count (0 if skipped or the +first run matched, else the number of *extra* runs actually executed +beyond the first): + +- **Skip the rerun** if the commit list already computed above + (`<last-primer-commit>..HEAD`) contains no file outside + `.session-continuity/` — no source or test file changed, so the recorded + count cannot have drifted. +- **Otherwise, run the test command(s) once.** Matches the primer's + recorded count → stop, no drift on this axis. +- **Only if that first run disagrees**, retry up to 2 more times (3 total) + to rule out flakiness. Pin to the count seen in ≥2 of 3 runs — if that + pinned count matches the primer, the first run was the flake and there's + no drift; if it still differs, report drift with the pinned count. If all + three runs disagree with each other, surface the spread (`saw 1162 / 1161 + / 1162 across 3 runs — using 1162; suite is unstable`) instead of + silently picking one. + +Common cases stay cheap: zero test runs when nothing relevant changed, one +run when the count still holds, three only when there's an actual +discrepancy to resolve. +``` + +Replace it with (mirrors `commands/primer.md:304-345` exactly — same script, +same output contract, same presentation-per-`MODE` rules — so both call sites +stay in lockstep by construction): + +```markdown +Run the shared test-count rerun script — the same one `commands/primer.md` +Step 4 item 3 calls, so both commands stay in lockstep — timed: + +```bash +_PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) +source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" 1; then + RERUN_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" . "$LAST_PRIMER_COMMIT" 2>&1)" + RERUN_STATUS=$? +else + RERUN_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + RERUN_STATUS=1 +fi +_PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") +_PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") +RETRIES=$(printf '%s' "$RERUN_OUTPUT" | awk -F= '/^RETRIES=/{print $2}') +echo "$RERUN_OUTPUT" +echo "RERUN_STATUS=$RERUN_STATUS" +``` + +Run this as the **same Bash tool call** as the pre-existing perf-log block a +few lines below ("At the end of this Bash call (whichever branch above +ran):", unmodified by this task) — that block reads `$_PERF_DURATION` and +`$RETRIES` from this one. A separate tool invocation would see both empty +and silently log a wrong duration/retries. + +**If `RERUN_STATUS` is nonzero, or `$RERUN_OUTPUT` has no `MODE=` line:** +report `$RERUN_OUTPUT` to the user and fall back to `TBD` for this axis — +never fabricate a drift verdict from a failed script. + +**Otherwise**, report per `MODE`: +- `skip` — no relevant file changed; say nothing (matches today's silent + skip). +- `no-command` — no test command recorded; nothing to check. +- `no-count`, `RETRIES=0`, `DRIFT=0` always — nothing recorded yet to + compare against; no report needed on this axis. +- `run` with `DRIFT=0` — the count held (whether on the first try or after + majority-vote confirmation); no report needed. +- `run` with `DRIFT=1` — report drift using `PINNED_COUNT` (`"Test count + drifted: recorded <RECORDED_COUNT>, now <PINNED_COUNT> (confirmed over + <RETRIES>+1 runs)."`). +- `run` with `SPREAD=1` — report instability using the comma-joined + `OBSERVED` values (`"Test suite is unstable: saw <OBSERVED, /-joined> + across 3 runs."`), not a drift verdict. +- `run` with `UNPARSEABLE=1` and no `PINNED_COUNT` — report `"Test command + produced no parseable count after <RETRIES>+1 attempts."` +``` + +(The nested code fence above is literal — `end-session.md` already contains +markdown-inside-markdown at every other Bash-call step in this file; match +the existing fence style around it exactly rather than introducing a new +convention.) + +- [ ] **Step 2: Fix the refresh flow's stale reference to manual retries** + +In `commands/end-session.md`, find (currently line 281, inside "### Refresh +flow"): + +```markdown +2. If the primer has a test-counts section and the counts changed (after the 3× retry), update them to match current output. +``` + +Replace with: + +```markdown +2. If `MODE=run` and `DRIFT=1` (per the test-count rerun script's output + above), update the test-counts section to `PINNED_COUNT`. +``` + +- [ ] **Step 3: Verify the file still renders correctly** + +Run: `grep -c '^```' commands/end-session.md` +Expected: an even number (every fence opened is closed). Compare against the +count before this edit (`git show HEAD:commands/end-session.md | grep -c +'^```'`) — the two edits above replace one fenced block with one fenced +block and touch no other fence, so the count should be unchanged. + +- [ ] **Step 4: Confirm the removed phrases are gone** + +Run (as two independent checks — the original prose wraps "logic" and +"lives in Step 5.3" across a markdown line break, so a single pattern +spanning both words would never match even before this fix and would prove +nothing): + +```bash +grep -inE 'Pin to the count seen in|Step 5\.3|after the 3× retry' commands/end-session.md +``` +Expected: no output. + +- [ ] **Step 5: Commit** + +```bash +git add commands/end-session.md +git commit -m "fix: end-session.md's drift check now calls test-count-rerun.sh (closes #54)" +``` + +## Task 2: `hooks/derived-value-gate.sh` + smoke test + +**Files:** +- Create: `hooks/derived-value-gate.sh` +- Create: `meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh` + +**Interfaces:** +- Consumes: `hooks/lib/gate-common.sh`'s `gate_load`, `gate_is_commit`, + `gate_scan_staged`, `gate_has_escape`, `gate_mask_escape`, `deny` (all + existing, unmodified). `meta/superpowers/validation/lib/gate-test-common.zsh`'s + `gt_make_repo`, `gt_stage`, `gt_commit_payload`, `gt_run`, `gt_is_deny`, + `gt_cleanup` (all existing, unmodified). +- Produces: `hooks/derived-value-gate.sh`, an executable script taking the + same stdin-JSON payload shape as the other six gates. No other file + consumes this in this plan (Task 3 wires it into `hooks.json`). + +- [ ] **Step 1: Write the failing smoke test** + +Create `meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh`: + +```zsh +#!/usr/bin/env zsh +set -uo pipefail +HERE="${0:A:h}" +source "$HERE/lib/gate-test-common.zsh" +pass=0; fail=0 +check() { if [[ "$2" == "$3" ]]; then print -r -- "ok - $1"; ((pass++)); else print -r -- "FAIL - $1 (want $2 got $3)"; ((fail++)); fi } +verdict() { gt_is_deny "$1" && print deny || print allow; } + +# 1. duration: epoch-subtraction idiom -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/end-session.md" $'prior_epoch="$(date -u -j -f \'%Y-%m-%dT%H:%M:%SZ\' "$prior_ts" +%s)"\n_DUR="$(( now_epoch - prior_epoch ))"\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "epoch subtraction -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 2. count/tally: majority-vote-by-eye phrase -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/primer.md" $'Pin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "pin-to-count phrase -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 3. compare claimed-vs-actual: eyeball-diff phrase -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/doctor.md" $'Does the git log --oneline -5 block inside it match the git log --oneline -5 output above?\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "does-X-match-Y-above -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 4. print-verbatim: reference-doc-as-instruction phrase -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/learning.md" $'Never omit it. Never replace it with paraphrased prose.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "never-paraphrase phrase -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 5. safe: names a script that owns the computation -> allow +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/learning.md" $'Run `bash hooks/lib/learnings-index.sh report`, which prints `MAX <n>`. Use that value.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "delegates to named script -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 6. escape hatch (decorated) -> allow even with a violation present +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/end-session.md" $'> **Derived-value-gate:** N/A — quoting the old prose in a changelog entry.\nPin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "decorated escape -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 7. out-of-scope path (not commands/*.md) -> allow even with a violation present +repo="$(gt_make_repo)" +gt_stage "$repo" "meta/notes.md" $'Pin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "out-of-scope path -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 8. dot-prefixed scratch file under commands/ -> allow (skipped) +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/.scratch.md" $'Pin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "scratch file skipped -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 9. sanity: the real, current commands/*.md content (post-#54-fix) is clean +repo="$(gt_make_repo)" +REPO_ROOT="${HERE:h:h:h}" +for f in "$REPO_ROOT"/commands/*.md; do + gt_stage "$repo" "commands/${f:t}" "$(cat "$f")" +done +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "real commands/*.md content -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +print -r -- "---"; print -r -- "pass=$pass fail=$fail"; [[ $fail -eq 0 ]] +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `zsh meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh` +Expected: every case FAILs (or the run errors) — `hooks/derived-value-gate.sh` +doesn't exist yet, so `gt_run` can't find it. + +- [ ] **Step 3: Write minimal implementation** + +Create `hooks/derived-value-gate.sh`: + +```bash +#!/usr/bin/env bash +# derived-value-gate.sh — commit-time content gate (session-continuity plugin, +# Determinism Phase 7, closes #44). +# +# Fires before Bash(git commit *). For each staged commands/*.md file, BLOCKS +# prompt text instructing a model to (1) compute a duration by hand, (2) +# tally/vote on a count by eye, (3) eyeball-compare a claimed value against an +# actual one, or (4) print fixed reference text as if it were an instruction — +# the four defect classes Phases 0-6 of the determinism program removed. See +# meta/superpowers/specs/2026-09-02-determinism-program-design.md and +# meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md +# for the grounding (which real diff each pattern below is anchored to). +# +# A fifth class named in #44 — "renumber" — is deliberately NOT checked here: +# no real removed instance exists to ground a pattern on (see the plan above), +# and a naive word-anchor false-positives on learning.md's own anti-renumber +# stability guarantees. +# +# Escape: `Derived-value-gate: N/A — <reason>`. +set -euo pipefail +# shellcheck disable=SC1091 # dynamically-resolved path; gate-common.sh is shellcheck-clean standalone +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/gate-common.sh" + +# shellcheck disable=SC2329 # called indirectly by gate_scan_staged +gate_in_scope() { + case "$1" in commands/*.md) return 0 ;; *) return 1 ;; esac +} + +# Each check takes (masked-content, path) and calls deny (exits) on a hit. +# Citation format matches occurrence-gate.sh's own: grep -n gives "N:match". + +_dvg_deny() { # <path> <label> <hit "N:text"> <explanation> + local path="$1" label="$2" hit="$3" explanation="$4" line matched + line="${hit%%:*}" + matched="$(printf '%s' "${hit#*:}" | cut -c1-120)" + deny "In staged file $path, line $line: $label (\"$matched\"). $explanation Add: Derived-value-gate: N/A — <reason> (decoration fine)." +} + +_dvg_check_duration() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE 'date -u -j -f|date -u -d "|\$\(\([^)]*_epoch[^)]*-[^)]*_epoch' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "instructs a model to compute a duration by hand (epoch subtraction)" "$hit" \ + "A script owns duration math — see hooks/lib/perf-log.sh's since subcommand." +} + +_dvg_check_count() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE 'cardinality|Pin to the count seen in|RETRIES count|across[[:space:]]+[0-9]+[[:space:]]+runs' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "instructs a model to tally or vote on a count by eye" "$hit" \ + "A script owns cardinality/majority-vote math — see hooks/lib/token-overlap.sh and hooks/lib/test-count-rerun.sh." +} + +_dvg_check_compare() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE 'match(es)?[[:space:]]+the[^.]*output above|disagrees with the recorded|does[^.]*match[^.]*above' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "instructs a model to eyeball-compare a claimed value against an actual one" "$hit" \ + "A script owns the comparison (an awk range extract plus diff, or the same shape as hooks/lib/primer-detect.sh)." +} + +_dvg_check_verbatim() { + local content="$1" path="$2" hit + hit="$(printf '%s' "$content" | grep -inoE 'not instructions to you|Illustrative only|List every file[^.]*do not summarize|Never omit it\. Never replace it with paraphrased prose|Always emit[^.]*exactly:' | head -1)" + [ -n "$hit" ] || return 0 + _dvg_deny "$path" "ships fixed reference text or a determinism-compensating instruction as prompt prose" "$hit" \ + "Fixed output belongs in the script that computes the values around it (skills/session-continuity/REFERENCE.md or a spec, not a command body)." +} + +# shellcheck disable=SC2329 # called indirectly by gate_scan_staged +gate_check() { + local content="$1" path="$2" masked + if gate_has_escape "$content" "Derived-value-gate"; then return 0; fi + masked="$(gate_mask_escape "$content" "Derived-value-gate")" + # Fixed priority order below (duration > count > compare > verbatim): a + # line tripping two categories at once is cited under the first one + # checked, not necessarily the earliest line in the file. Harmless — one + # escape hatch clears every category — but worth knowing when reading a + # denial that names a category other than the one you expected. + _dvg_check_duration "$masked" "$path" + _dvg_check_count "$masked" "$path" + _dvg_check_compare "$masked" "$path" + _dvg_check_verbatim "$masked" "$path" +} + +gate_load +gate_is_commit || exit 0 +gate_scan_staged gate_in_scope gate_check +exit 0 +``` + +Run: `chmod +x hooks/derived-value-gate.sh` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `zsh meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh` +Expected: `pass=9 fail=0`. + +If case 9 (the real-file sanity check) fails, do not weaken the pattern to +force a pass — that means either Task 1 didn't fully remove the offending +phrase, or a pattern is broader than intended. Re-read the denial's cited +line and fix the root cause (the command file, or the pattern's specificity) +before re-running. + +- [ ] **Step 5: Commit** + +```bash +git add hooks/derived-value-gate.sh meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh +git commit -m "feat: add derived-value-gate.sh, the Phase 7 commit-time content gate" +``` + +## Task 3: Wire into `hooks.json` + +**Files:** +- Modify: `hooks/hooks.json` + +**Interfaces:** +- Consumes: `hooks/derived-value-gate.sh` (Task 2), `hooks/lib/perf-wrap.sh` + (existing, unmodified). + +- [ ] **Step 1: Add the gate to the `Bash` matcher group** + +In `hooks/hooks.json`, inside the `PreToolUse` → `matcher: "Bash"` array, +add a new entry immediately after the `occurrence-gate.sh` line (so the +Bash-matcher array reads: `pre-commit-check`, `flaky-gate`, `proven-gate`, +`smoke-gate`, `evidence-gate`, `backend-parity-gate`, `occurrence-gate`, +`derived-value-gate`, `learnings-surface`): + +```json + { "type": "command", "if": "Bash(git commit *)", "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-wrap.sh derived-value-gate.sh" }, +``` + +- [ ] **Step 2: Validate JSON syntax** + +Run: `python3 -m json.tool hooks/hooks.json >/dev/null && echo OK` +Expected: `OK`. + +- [ ] **Step 3: Re-run the smoke test (regression check on the wiring)** + +Run: `zsh meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh` +Expected: `pass=9 fail=0` (unchanged — this step doesn't touch the gate's own +logic, only its registration). + +- [ ] **Step 4: Sanity-check against this repo's own real staged state** + +Run: +```bash +git add -A +bash hooks/derived-value-gate.sh <<<"$(printf '{"tool_name":"Bash","cwd":"%s","tool_input":{"command":"git commit -m x"}}' "$(pwd)")" +``` +Expected: no output (silent allow) — confirms the gate, wired exactly as it +will run in production, denies nothing against the real, currently-staged +repo state. Run `git reset` afterward to unstage (this step is a dry run, +not an actual commit). + +- [ ] **Step 5: Commit** + +```bash +git add hooks/hooks.json +git commit -m "feat: wire derived-value-gate.sh into hooks.json" +``` + +## Task 4: Doc pointers, `SECURITY.md` correction, changelog, version bump + +**Files:** +- Modify: `SECURITY.md:39-42` +- Modify: `meta/superpowers/specs/2026-09-02-determinism-program-design.md:242-249` +- Modify: `CHANGELOG.md` +- Modify: `.claude-plugin/plugin.json` + +- [ ] **Step 1: Correct `SECURITY.md`'s stale hook-matcher-scope section** + +In `SECURITY.md`, find (currently lines 39–42): + +```markdown +- **Hook matcher scope.** `hooks/hooks.json` registers one `SessionStart` hook and seven `PreToolUse` hooks, split across two matcher groups: + - `matcher: "Bash"` — `pre-commit-check.sh` and `flaky-gate.sh`'s commit-message check both carry a per-hook `if: Bash(git commit *)` filter, so they only spawn on `git commit`. `learnings-surface.sh` has no `if` filter in this group — it spawns on every `Bash` call, not just commits, since its job is to match the imminent command text against LEARNINGS trigger regexes. + - `matcher: "Write|Edit"` — `learnings-surface.sh`, `smoke-gate.sh`, `proven-gate.sh`, `occurrence-gate.sh`, `evidence-gate.sh`, `flaky-gate.sh`, and `backend-parity-gate.sh` all spawn on every `Write`/`Edit` call. Each self-scopes internally (by file path pattern — plan files, spec files, or `LEARNINGS.md`) and exits 0 immediately for files outside its scope, so the broad matcher is narrowed in-script rather than in `hooks.json`. + - Five of these seven (`smoke-gate`, `proven-gate`, `occurrence-gate`, `evidence-gate`, `backend-parity-gate`, and `flaky-gate`'s Write/Edit path) can return `permissionDecision:"deny"` and block the tool call — the others (`session-start.sh`, `pre-commit-check.sh`, `learnings-surface.sh`) are non-blocking, `permissionDecision:"allow"` or silent-exit only. +``` + +Replace with (matches the real, current `hooks.json` after Task 3 — verify +the hook count against `grep -c '"type"' hooks/hooks.json` before committing, +since a future gate addition will make this stale again): + +```markdown +- **Hook matcher scope.** `hooks/hooks.json` registers one `SessionStart` hook (`session-start.sh`), one `UserPromptSubmit` hook (`prompt-intercept.sh`), and ten `PreToolUse` hooks, split across two matcher groups: + - `matcher: "Bash"` — nine hooks. Eight carry a per-hook `if: Bash(git commit *)` filter (`pre-commit-check.sh`, `flaky-gate.sh`, `proven-gate.sh`, `smoke-gate.sh`, `evidence-gate.sh`, `backend-parity-gate.sh`, `occurrence-gate.sh`, `derived-value-gate.sh`) so they only spawn on `git commit`. `learnings-surface.sh` has no `if` filter — it spawns on every `Bash` call, not just commits, since its job is to match the imminent command text against LEARNINGS trigger regexes. + - `matcher: "Write|Edit"` — `learnings-surface.sh` only. + - Seven of the nine `Bash`-matcher hooks are content gates that can return `permissionDecision:"deny"` and block the tool call: `flaky-gate`, `proven-gate`, `smoke-gate`, `evidence-gate`, `backend-parity-gate`, `occurrence-gate`, and `derived-value-gate`. The rest (`pre-commit-check.sh`, `learnings-surface.sh`, `session-start.sh`, `prompt-intercept.sh`) are non-blocking, `permissionDecision:"allow"` or silent-exit only. +``` + +- [ ] **Step 2: Collapse the program design doc's Phase 7 entry to a pointer** + +In `meta/superpowers/specs/2026-09-02-determinism-program-design.md`, find +(currently lines 242–249): + +```markdown +**Phase 7 `#44` — the gate that keeps it true.** A commit-time content gate on +staged `commands/*.md` that blocks prompt text instructing a model to count, +tally, renumber, compute a duration, compare a claimed value against an +actual one, or print fixed text verbatim, with the usual +`<Gate-name>: N/A — <reason>` escape. This is the reconciler-level enforcement +of the invariant; every other phase is a one-time cleanup that decays without +it. Ships last because the gate's pattern list should be written from what the +earlier phases actually removed, not guessed beforehand. +``` + +Replace with (matching the "entry format" convention this doc states at +lines 154–159 — once a phase has its own artifact, its entry collapses to a +pointer): + +```markdown +**Phase 7 `#44` — the gate that keeps it true.** Shipped as +`hooks/derived-value-gate.sh`, covering four of the five originally-scoped +classes (renumber dropped — no grounded removal exists to anchor it on). +Also fixed `#54` (an un-migrated duplicate of Phase 6-B's majority-vote logic +that the gate's own count pattern would otherwise have immediately flagged). +Plan: `meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md`. +``` + +- [ ] **Step 3: Bump the version and changelog** + +In `.claude-plugin/plugin.json`, change `"version": "0.34.0"` to +`"version": "0.35.0"`. + +In `CHANGELOG.md`, insert a new entry directly above the existing +`## [0.34.0] — 2026-09-09` heading: + +```markdown +## [0.35.0] — 2026-09-09 + +### Added +- **A seventh commit-time content gate, `hooks/derived-value-gate.sh`.** + Blocks new `commands/*.md` prompt text that instructs a model to compute a + duration by hand, tally/vote on a count by eye, eyeball-compare a claimed + value against an actual one, or print fixed reference text as if it were + an instruction — the reconciler-level enforcement of the determinism + program's invariant (every other phase is a one-time cleanup that decays + without this). Escape hatch: `Derived-value-gate: N/A — <reason>`. + +### Fixed +- **`end-session.md`'s drift check now calls `test-count-rerun.sh`** instead + of hand-deriving the same majority-vote rerun Phase 6-B already scripted + for `primer.md` — the two command files were computing the identical + algorithm two different ways. +``` + +- [ ] **Step 4: Verify the doc edits are internally consistent** + +Run: `grep -n '"version"' .claude-plugin/plugin.json` — confirm `0.35.0`. +Run: `head -8 CHANGELOG.md` — confirm the new entry is above `[0.34.0]`. + +Run (counts per event type from the real JSON structure, not by eyeballing +quote characters — `grep -c '"type"'` over the whole file would also catch +`SessionStart` and `UserPromptSubmit`, which is exactly the kind of +by-eye-miscount this plan exists to stop making): + +```bash +python3 -c " +import json +d = json.load(open('hooks/hooks.json'))['hooks'] +print('SessionStart:', sum(len(g['hooks']) for g in d.get('SessionStart', []))) +print('UserPromptSubmit:', sum(len(g['hooks']) for g in d.get('UserPromptSubmit', []))) +print('PreToolUse:', sum(len(g['hooks']) for g in d.get('PreToolUse', []))) +" +``` +Expected: `SessionStart: 1`, `UserPromptSubmit: 1`, `PreToolUse: 10` — matches +the counts named in the `SECURITY.md` edit above. + +- [ ] **Step 5: Close out the GitHub issues and commit** + +```bash +git add SECURITY.md meta/superpowers/specs/2026-09-02-determinism-program-design.md CHANGELOG.md .claude-plugin/plugin.json +git commit -m "docs: Phase 7 doc pointers, SECURITY.md correction, changelog, and version bump" +gh issue close 44 --reason completed +gh issue close 54 --reason completed +``` diff --git a/meta/superpowers/specs/2026-09-02-determinism-program-design.md b/meta/superpowers/specs/2026-09-02-determinism-program-design.md index df9067d..f2151e9 100644 --- a/meta/superpowers/specs/2026-09-02-determinism-program-design.md +++ b/meta/superpowers/specs/2026-09-02-determinism-program-design.md @@ -239,14 +239,12 @@ and D shipped; C and E stay parked until this plugin actually has external installs old enough to hit either path (tracked via `#35`, not reopened here speculatively). -**Phase 7 `#44` — the gate that keeps it true.** A commit-time content gate on -staged `commands/*.md` that blocks prompt text instructing a model to count, -tally, renumber, compute a duration, compare a claimed value against an -actual one, or print fixed text verbatim, with the usual -`<Gate-name>: N/A — <reason>` escape. This is the reconciler-level enforcement -of the invariant; every other phase is a one-time cleanup that decays without -it. Ships last because the gate's pattern list should be written from what the -earlier phases actually removed, not guessed beforehand. +**Phase 7 `#44` — the gate that keeps it true.** Shipped as +`hooks/derived-value-gate.sh`, covering four of the five originally-scoped +classes (renumber dropped — no grounded removal exists to anchor it on). +Also fixed `#54` (an un-migrated duplicate of Phase 6-B's majority-vote logic +that the gate's own count pattern would otherwise have immediately flagged). +Plan: `meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md`. ## Non-goals diff --git a/meta/superpowers/validation/2026-08-12-hook-json-contract-smoke.zsh b/meta/superpowers/validation/2026-08-12-hook-json-contract-smoke.zsh index 605f2e6..8cb3333 100755 --- a/meta/superpowers/validation/2026-08-12-hook-json-contract-smoke.zsh +++ b/meta/superpowers/validation/2026-08-12-hook-json-contract-smoke.zsh @@ -75,6 +75,8 @@ commit_parses "backend-parity-gate: one named only" \ backend-parity-gate.sh "meta/plans/p.md" 'This plan needs full backend parity coverage in smoke.' commit_parses "occurrence-gate: repeat, no invariant" \ occurrence-gate.sh ".session-continuity/LEARNINGS.md" $'Occurrence count: 3 of 5\nYet another trigger patch.' +commit_parses "derived-value-gate: duration computed by hand" \ + derived-value-gate.sh "commands/end-session.md" 'prior_epoch="$(date -u -j -f "%Y-%m-%dT%H:%M:%SZ" "$t" +%s)"' # Adversarial reasons: staged content carrying the characters that break a # hand-built JSON string. smoke-gate echoes the matched line into its @@ -113,7 +115,7 @@ prompt_parses "prompt-intercept: /session-continuity:help block parses" "/sessio # Completeness: every gate must own at least one fixture above. A newly added # gate fails this runner until someone adds one — that is the point. -covered=(proven-gate.sh smoke-gate.sh evidence-gate.sh flaky-gate.sh backend-parity-gate.sh occurrence-gate.sh) +covered=(proven-gate.sh smoke-gate.sh evidence-gate.sh flaky-gate.sh backend-parity-gate.sh occurrence-gate.sh derived-value-gate.sh) for f in "$hooks"/*-gate.sh; do b="${f:t}" if (( ${covered[(Ie)$b]} )); then diff --git a/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh b/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh index 9d4fba0..88051ca 100755 --- a/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh +++ b/meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh @@ -37,8 +37,8 @@ work="$(mktemp -d)" # against `grep -cE '^### [0-9]+\.'` directly (the naive expression is # correct here precisely because no real entry heading sits inside a # comment or a fence — that only happens in the shipped templates below). -# Pin last bumped 2026-09-09 (16 -> 20, four more entries landed since). -assert_count "real LEARNINGS.md" "$repo/.session-continuity/LEARNINGS.md" 20 +# Pin last bumped 2026-09-09 (20 -> 21, one more entry landed since). +assert_count "real LEARNINGS.md" "$repo/.session-continuity/LEARNINGS.md" 21 # count-entries.sh is file-format agnostic (LEARNINGS still uses it). A # synthetic markdown file pins the heading-count contract without depending diff --git a/meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh b/meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh new file mode 100644 index 0000000..d745d95 --- /dev/null +++ b/meta/superpowers/validation/2026-09-09-derived-value-gate-smoke.zsh @@ -0,0 +1,75 @@ +#!/usr/bin/env zsh +set -uo pipefail +HERE="${0:A:h}" +source "$HERE/lib/gate-test-common.zsh" +pass=0; fail=0 +check() { if [[ "$2" == "$3" ]]; then print -r -- "ok - $1"; ((pass++)); else print -r -- "FAIL - $1 (want $2 got $3)"; ((fail++)); fi } +verdict() { gt_is_deny "$1" && print deny || print allow; } + +# 1. duration: epoch-subtraction idiom -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/end-session.md" $'prior_epoch="$(date -u -j -f \'%Y-%m-%dT%H:%M:%SZ\' "$prior_ts" +%s)"\n_DUR="$(( now_epoch - prior_epoch ))"\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "epoch subtraction -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 2. count/tally: majority-vote-by-eye phrase -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/primer.md" $'Pin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "pin-to-count phrase -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 3. compare claimed-vs-actual: eyeball-diff phrase -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/doctor.md" $'Does the git log --oneline -5 block inside it match the git log --oneline -5 output above?\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "does-X-match-Y-above -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 4. print-verbatim: reference-doc-as-instruction phrase -> deny +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/learning.md" $'Never omit it. Never replace it with paraphrased prose.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "never-paraphrase phrase -> deny" "deny" "$(verdict "$out")" +gt_cleanup "$repo" + +# 5. safe: names a script that owns the computation -> allow +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/learning.md" $'Run `bash hooks/lib/learnings-index.sh report`, which prints `MAX <n>`. Use that value.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "delegates to named script -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 6. escape hatch (decorated) -> allow even with a violation present +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/end-session.md" $'> **Derived-value-gate:** N/A — quoting the old prose in a changelog entry.\nPin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "decorated escape -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 7. out-of-scope path (not commands/*.md) -> allow even with a violation present +repo="$(gt_make_repo)" +gt_stage "$repo" "meta/notes.md" $'Pin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "out-of-scope path -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 8. dot-prefixed scratch file under commands/ -> allow (skipped) +repo="$(gt_make_repo)" +gt_stage "$repo" "commands/.scratch.md" $'Pin to the count seen in 2 of 3 runs.\n' +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "scratch file skipped -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +# 9. sanity: the real, current commands/*.md content (post-#54-fix) is clean +repo="$(gt_make_repo)" +REPO_ROOT="${HERE:h:h:h}" +for f in "$REPO_ROOT"/commands/*.md; do + gt_stage "$repo" "commands/${f:t}" "$(cat "$f")" +done +out="$(gt_run derived-value-gate.sh "$(gt_commit_payload "$repo")")" +check "real commands/*.md content -> allow" "allow" "$(verdict "$out")" +gt_cleanup "$repo" + +print -r -- "---"; print -r -- "pass=$pass fail=$fail"; [[ $fail -eq 0 ]] From 80f375338c0dc5fce43e7d5b33a06c3fac52ce66 Mon Sep 17 00:00:00 2001 From: Tal Golan <tg+github@nd.io> Date: Wed, 9 Sep 2026 16:47:41 -0700 Subject: [PATCH 20/20] =?UTF-8?q?feat:=20thin=20hard-template=20SESSION=5F?= =?UTF-8?q?PRIMER=20(0.36.0)=20=E2=80=94=20engrim=20+=20graphify=20peers?= =?UTF-8?q?=20(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: thin hard-template SESSION_PRIMER design (engrim + graphify) Locks Approach A: fixed Boot/Mid-flight/Confirm/Peers, validator + peer probes, hard incomplete when peers missing. Spec only — no product code. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: add thin hard-template SESSION_PRIMER impl plan (#62) Stage the plan and primer refresh so Task 1+ can branch from a recorded baseline. Co-authored-by: Cursor <cursoragent@cursor.com> * feat: peer-probes.sh for engrim + graphify-out/graph.json Co-authored-by: Cursor <cursoragent@cursor.com> * feat: primer-validate.sh hard-template + banlist gate Co-authored-by: Cursor <cursoragent@cursor.com> * feat: primer-freshness.sh basename-aware stale probe Co-authored-by: Cursor <cursoragent@cursor.com> * test: make primer-freshness smoke sandbox-safe (empty git template) Co-authored-by: Cursor <cursoragent@cursor.com> * feat: thin SESSION_PRIMER template + peer boot copy Co-authored-by: Cursor <cursoragent@cursor.com> * feat: SessionStart peer hard-stop + missing-primer nudge Co-authored-by: Cursor <cursoragent@cursor.com> * feat: doctor validates primer shape, peers, freshness Co-authored-by: Cursor <cursoragent@cursor.com> * feat: thin primer refresh/slim-migrate; drop git-log regen Co-authored-by: Cursor <cursoragent@cursor.com> * feat: thin hard-template SESSION_PRIMER (0.36.0) — engrim + graphify peers Co-authored-by: Cursor <cursoragent@cursor.com> * docs: align README primer refresh with thin hard-template Replace retired git-log drift language with Mid-flight/Confirm refresh and primer-freshness.sh. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: drop git-log regen from SKILL maintenance rules Align shipped skill prose with thin hard-template: Mid-flight/Confirm refresh + primer-validate/freshness/peers; banlist git-log dumps. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> --- .claude-plugin/plugin.json | 2 +- .session-continuity/PROJECT_CONTEXT.md | 6 +- .session-continuity/SESSION_PRIMER.md | 729 +- CHANGELOG.md | 10 + PRIVACY.md | 4 +- README.md | 10 +- commands/doctor.md | 53 +- commands/end-session.md | 140 +- commands/primer.md | 233 +- graphify-out/graph.json | 28498 ++++++++++++++++ hooks/lib/peer-probes.sh | 34 + hooks/lib/primer-freshness.sh | 38 + hooks/lib/primer-validate.sh | 165 + hooks/pre-commit-check.sh | 2 +- hooks/session-start.sh | 68 +- .../2026-09-09-primer-thin-hard-template.md | 467 + ...-09-09-primer-thin-hard-template-design.md | 333 + .../2026-08-12-session-start-smoke.zsh | 79 +- .../2026-09-09-peer-probes-smoke.zsh | 109 + .../2026-09-09-primer-freshness-smoke.zsh | 137 + .../2026-09-09-primer-validate-smoke.zsh | 242 + .../2026-09-09-session-start-peers-smoke.zsh | 80 + skills/session-continuity/SKILL.md | 15 +- .../templates/CLAUDE_MD_SNIPPET.md | 24 +- .../templates/PROJECT_CONTEXT.md | 6 +- .../templates/SESSION_PRIMER.md | 49 +- 26 files changed, 30550 insertions(+), 983 deletions(-) create mode 100644 graphify-out/graph.json create mode 100755 hooks/lib/peer-probes.sh create mode 100755 hooks/lib/primer-freshness.sh create mode 100755 hooks/lib/primer-validate.sh create mode 100644 meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md create mode 100644 meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md create mode 100755 meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh create mode 100755 meta/superpowers/validation/2026-09-09-primer-freshness-smoke.zsh create mode 100755 meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh create mode 100755 meta/superpowers/validation/2026-09-09-session-start-peers-smoke.zsh diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 91f358c..b1122d3 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "session-continuity", - "version": "0.35.0", + "version": "0.36.0", "description": "Cross-session memory for Claude Code projects via four in-repo docs: SESSION_PRIMER.md (current state), PROJECT_CONTEXT.md (stable repo context), ROADMAP.md (strategic direction), and LEARNINGS.md (hard-won bugs), plus GitHub Issues labeled backlog for the work queue.", "author": { "name": "Tal Golan" diff --git a/.session-continuity/PROJECT_CONTEXT.md b/.session-continuity/PROJECT_CONTEXT.md index f517b9f..7b641ce 100644 --- a/.session-continuity/PROJECT_CONTEXT.md +++ b/.session-continuity/PROJECT_CONTEXT.md @@ -95,9 +95,9 @@ In order of cost: ## Maintenance (your responsibility) This file changes rarely — only when the project's shape changes (new -module, new convention, moved directory). For the file that changes with -every substantive commit, see `.session-continuity/SESSION_PRIMER.md` and -its own "Primer maintenance" section. +module, new convention, moved directory). On substantive commits, refresh +Mid-flight + Confirm in `.session-continuity/SESSION_PRIMER.md` and stage +it with the commit. When you do edit this file, stage it alongside the change that made the edit necessary — same non-standalone-commit discipline as the primer. diff --git a/.session-continuity/SESSION_PRIMER.md b/.session-continuity/SESSION_PRIMER.md index 61e7ad8..62c3932 100644 --- a/.session-continuity/SESSION_PRIMER.md +++ b/.session-continuity/SESSION_PRIMER.md @@ -1,709 +1,28 @@ # Session Primer — session-continuity -You are picking up work on session-continuity from a previous session. -This file is the shortest path to what changed recently and what's -outstanding. For stable repo context (layout, conventions, modules), read -`.session-continuity/PROJECT_CONTEXT.md` once per session — it changes -rarely. - -## First things first (read these before touching anything) - -1. **`.session-continuity/PROJECT_CONTEXT.md`** — stable repo context: - layout, conventions, where to look for what. -2. **`CLAUDE.md`** at the repo root — project conventions, runtime - choices, never-commit-secrets rules. -3. **`.session-continuity/LEARNINGS.md`** — graveyard of subtle bugs, - grouped by layer. If you hit something weird, grep this file first. -4. **Session memory system** (MemPalace, or whatever the user has in - place) — prior sessions may have left searchable context. Query - before guessing. - -## Current state - -- **Determinism Phase 6 sub-project A shipped (issue #43 partially — - 4 of 5 sub-projects remain, PR #52, merged).** `commands/primer.md` - Step 1's hand-evaluated 4-state-plus-3-migration-trigger dispatch - (~15 lines of nested-conditional prose with an easy-to-miss sequencing - rule) replaced by `hooks/lib/primer-detect.sh`/`.jq`, which threads - each trigger's effect forward into the fact the next trigger reads - (`outstanding_split`→`backlog_rename`→`backlog_to_issues`) rather than - writing per-trigger "OR about to become true" disjunctions — that - approach was tried during implementation-first verification, found not - to compose past one chained link (a real bug caught twice: once by - caveman-review, once by re-deriving the logic directly in jq), and - replaced. Executed via subagent-driven-development (3 tasks, each - task-reviewed) plus a final whole-branch review (Opus) that found one - more real gap before merge: the terminal-step rule only ran Step 5 - when `STEPS` was fully empty, silently skipping the status report for - a migration-only `STEPS` list — fixed, re-reviewed clean. 16/16 smoke - assertions (real scratch git repos). Design spec: - `meta/superpowers/specs/2026-09-08-primer-detect-design.md`. Plan: - `meta/superpowers/plans/2026-09-08-primer-detect.md`. Sub-projects - B (Step 4's test-count majority-vote rerun), C (Step 3c/3d's `git - mv`/`git rm` mechanics), D (Step 2's placeholder derivation), and E - (Step 3/3b's section-bucketing judgment) remain pending on issue #43. - One parked minor: the corrected terminal-step rule also fires Step 5 - after `STEPS=init` on every fresh install (Step 2 already prints its - own terminal report) — harmless, one extra status paragraph, happens - once per repo ever. v0.32.0. -- **Determinism Phase 5 re-scoped and shipped (issue #42, branch - `determinism-phase-5-token-overlap`).** Original scoping conflated two - unrelated things: `candidate-extract.jq`'s `overlap()` (a Jaccard ratio - for LEARNINGS-candidate dedup — already fixed and closed as #40, see - the bullet below, unrelated to this work) and the commit-subject / - backlog-issue-title cardinality-threshold gate duplicated as two prose - copies inside `commands/end-session.md` (the "Overlap gate" in Backlog - verification and the refresh flow's "backlog overlay" — primer.md's own - copy had already vanished with the GitHub Issues migration, so it was - never really "shared with primer.md" as originally framed). Shipped - `hooks/lib/token-overlap.sh`/`.jq`: tokenize, drop stopwords, intersect, - threshold ≥3, computed once per `end-session` run and reused by both - call sites; stopword list moved out of prose into the `.jq` filter. - 6 fixture cases verified (real match, near-miss, stopword-only overlap, - empty issues/commits, multiplicity dedup, missing-file failure) — see - `meta/superpowers/validation/2026-09-08-token-overlap.md`. v0.31.0. -- **Closes backlog #40: `overlap()`'s asymmetric Jaccard in - `hooks/lib/candidate-extract.jq` over-merged distinct retry-bursts.** - The numerator (`$wa - ($wa - $wb)`) counted `$wa`'s own word - *multiplicity*, while the denominator (`$u`) was deduped — a repeated - word inside one candidate's title (e.g. a command whose args happen to - contain "file", which also sits in the "— re-run N times with M file - edits in between." boilerplate) inflated that title's similarity score - against an unrelated candidate enough to cross the 0.7 dedup threshold - and get it wrongly dropped. Fixed by deduping `$wa`/`$wb` before - intersecting (`unique` added at both `title_words` call sites), making - the ratio a real Jaccard index and direction-symmetric. New regression - case in `meta/superpowers/validation/2026-09-01-candidate-extract-smoke.zsh` - (two genuinely distinct retry-bursts — one command's args repeat "file" - — must both survive dedup); verified end-to-end pre-fix collapse (1 - candidate) vs. post-fix (2) via a real transcript fixture through - `candidate-extract.sh`, not just the isolated `overlap()` filter. Full - suite 31/31 green. -- **Backlog #38 (docguard generalization) — this repo's side merged, the - actual mechanism not yet activated.** PR - https://github.com/talgolan/session-continuity/pull/49 (merged - 2026-09-08) updates this repo's design doc - (`meta/superpowers/recommendations/docguard-design-sketch.md`) to record - the mechanism as built. The actual code — a hand-rolled `.docguard.yml` - parser and `~/.githooks/post-merge` wiring — lives on branch - `docguard-generalization` in `~/.githooks`, a *separate* git repo - (discovered mid-session: `~/.githooks` is not its own repo, it's a - subdirectory of a personal dotfiles repo rooted at `$HOME` with a - blanket exclude + per-file force-add; `post-merge` had never been - tracked there before this work). That branch is intentionally kept - unmerged: merging would make git try to check out a newly-tracked - `post-merge` over the path where the live, still-untracked hook sits, - which needs a deliberate reconciliation step first. Issue #38 stays open - until that lands. Plan: - `meta/superpowers/plans/2026-09-08-docguard-generalization.md` (this - repo, untracked by design — a working record, not shipped content). -- **v0.29.0 released** — GitHub Issues labeled `backlog` replace `.session-continuity/BACKLOG.md`. Merged to `main` via PR #47 (`999e1f2`), tag `v0.29.0`, release https://github.com/talgolan/session-continuity/releases/tag/v0.29.0. Identity is `#N`; LEARNINGS stays a local file. This repo's live items are issues #35–#45. -- **v0.27.1 — gate-escape self-condemnation hazard fixed, merged to `main` - via PR #33 (`dd84ee7`) and released (tag `v0.27.1`, bumped in `c00cf17`).** - Backlog: architect-workbench's `4e81` / this repo's own - writeup in `COMMIT_HOOKS.md` §4 tracked a hazard where a gate's own - `Label: N/A` escape hatch matches that same gate's claim-trigger regex, so - any failure of the escape check turns the exemption line into the sole - claim that condemns the doc. `gate_mask_escape`/`gate_first_match` added to - `hooks/lib/gate-common.sh`; wired into `proven-gate.sh`, `flaky-gate.sh`, - `smoke-gate.sh`, and (this session — found unpatched despite having smoke - tests already written for it) `backend-parity-gate.sh`. `evidence-gate.sh` - and `occurrence-gate.sh` audited and left alone: their escape labels don't - overlap their own claim vocabulary, so they were never exposed. Also fixed - in this session: `smoke-gate.sh`'s binary/engine fallback check was still - reading raw `$content` after the weak-smoke branch above it had been - converted to the masked `$scan` — see LEARNINGS #16. All six - `*-gate*-smoke.zsh` suites pass (proven 10/10, flaky 10/10, smoke 9/9, - backend-parity 7/7, evidence 7/7, occurrence 6/6, gate-common 18/18). - `2026-09-02-render-smoke.zsh`'s 2 failures are pre-existing on this branch's - base and unrelated (a backlog-render count mismatch); left untouched. - `LEARNINGS.md` gained entry #16 documenting the partial-migration hazard - for this class of gate bug (masking one raw-`$content` check but missing - a sibling one). - -- **v0.27.0 — `end-session` Step 2's rendering made conditional, not - unconditional, merged to `main` via PR #32 (`d3b5feb`) and released - (tag `v0.27.0`, bumped in `ad0f50d`).** Roughly 160 of - `commands/end-session.md`'s 790 lines described what - `hooks/lib/candidate-extract.jq` already decides and handed the model a - formatting job it did unreliably (three anti-drift instructions existed - because of it). Two new sibling scripts — `hooks/lib/resolve-transcript.sh` - and `hooks/lib/candidate-render.sh` — resolve the transcript path and - render the finished candidate block deterministically; the relocated - heuristics prose now lives in new `skills/session-continuity/HEURISTICS.md`, - read only when there's no script-derived answer (no transcript, a - stale/unreadable one, or a missing/outdated script). Step 4's - `agent-active.sh` call (`175c1e4`) now resolves the transcript on demand - too, instead of depending on a shell variable set in Step 2's separate - Bash call. New smoke suites `meta/superpowers/validation/2026-09-02- - candidate-render-smoke.zsh` (9/9) and `2026-09-02-resolve-transcript- - smoke.zsh` (5/5). Plan: `meta/superpowers/plans/2026-09-02-end-session- - step2-rendering-plan.md`. -- **v0.26.0 — Determinism program Phase 1 ("zero-turn read-only commands"), - merged to `main` via PR #31 (`d99054d`) and released (tag `v0.26.0`, - GitHub release auto-published from the tag). Closes backlog item `[5c2d]` - (now a one-line closed stub).** Retires - `/session-continuity:backlog`, `/session-continuity:learnings`, - `/session-continuity:help`, and `/session-continuity:update` to zero model - calls in the common case. Task 1 (`9b33acf`) measured the - `UserPromptSubmit` interception surface (four hook behaviors, empirically - confirmed). Task 2 (`eb85948`, `909c494`) shipped `hooks/lib/render.sh` - plus two `.awk` siblings — a pure renderer, zero model calls when invoked - directly; new smoke suite `meta/superpowers/validation/2026-09-02-render- - smoke.zsh` 40/40. Task 3 (`1b60892`) shipped `hooks/prompt-intercept.sh`, - registered as a new `UserPromptSubmit` hook in `hooks/hooks.json` — - intercepts the fixed table (backlog/learnings natural language plus the - fully plugin-scoped slash forms of all four commands) and blocks the - prompt, answering with `render.sh`'s output directly; fails open on every - ambiguity (no `jq`, unparseable payload, non-exact match, `render.sh` - missing/erroring/silent). New smoke suite `meta/superpowers/validation/ - 2026-09-02-prompt-intercept-smoke.zsh` 44/44; the pre-existing hook-JSON - contract runner (`meta/superpowers/validation/2026-08-12-hook-json- - contract-smoke.zsh`), extended to cover the new hook, 19/19. Task 4 - (`cf6746e`) added `commands/backlog.md` and `commands/learnings.md` - (new), and retrofitted `commands/help.md` and `commands/update.md` — all - four are now one-Bash-call-then-print-verbatim fallback bodies, used only - when the hook doesn't fire. Task 6 (this entry): doc/changelog/version - bookkeeping — `SKILL.md`'s inline command list, `REFERENCE.md`'s hook - table (new `prompt-intercept.sh` bullet with its fail-open contract - spelled out, plus a pointer from the standing backlog-numbering rule to - `render.sh backlog` as the canonical shape), and `README.md` (command - count, table rows, prose subsections) all updated seven→nine commands; - `plugin.json` 0.25.2→0.26.0; filed backlog item #45 (concrete - `/session-continuity:doctor` retrofit, deferred until architectural item - `4a9d` decides whether `/doctor` becomes a zero-turn script at all — this - phase deliberately did not touch `/doctor`). Final whole-branch review - (opus) found one real cross-task defect: `hooks/lib/count-entries.sh` - diverged from `render-backlog.awk`/`render-learnings.awk` on a - self-closing inline HTML comment on a heading line (counted a line the - renderers never rendered) — fixed in `117b8bc`, plus a stale hardcoded - BACKLOG-count pin in that same smoke suite (`bf15d9d`, from Task 6's own - BACKLOG.md edit). All 19 hermetic smoke suites re-run green pre-merge. - Plan: `meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md`. - Design spec: `meta/superpowers/specs/2026-09-02-zero-turn-read-only- - commands-design.md`. Post-merge: local `main` had an unpushed - backlog-item-8-closing commit predating this branch's fork point, - rebased onto merged `main` and pushed (`d9ea464`); backlog items `[6258]`, - `[3b71]`, `[5c2d]` are now one-line closed stubs (kept, not deleted — all - three tags are cross-referenced in `ROADMAP.md`/`RESUME.md`/other specs, - per this file's own grep-before-delete rule). -- **v0.25.2 — Determinism Phase 0 (fresh-install count defects), committed on - branch `worktree-fresh-install-count-defects` (worktree - `fresh-install-count-defects`), not yet merged/released.** Fixes two real - bugs affecting every fresh install: (1) a fresh project's SessionStart - banner and `/session-continuity:primer` check mode both reported nonzero - backlog/learnings counts because the shipped templates' exemplar headings - (`templates/LEARNINGS.md`'s `### 1./2. {{ENTRY_TITLE}}`, - `templates/BACKLOG.md`'s commented `### 1. [a3f9] …`) matched the same - pattern used to count real entries — `templates/LEARNINGS.md`'s exemplar - headings are now commented out (`3c996f7`); (2) `grep -c ... || echo 0` - printed two `0` lines instead of one at the exact zero count it was meant - to handle. Both fixed by routing through one new helper, - `hooks/lib/count-entries.sh` (comment-and-fence-aware, single definition of - "how many entries does this file have"; `f18434b`), wired into - `hooks/session-start.sh` (also fixing a shortlist-gating bug; `721b287`) - and `commands/primer.md` check mode (also removing a stale cross-reference - to a file Init mode never creates; `a26a062`). Along the way, `721b287` - repaired the previously-stale `meta/superpowers/validation/2026-08-12-session-start-smoke.zsh` - (7 of 17 assertions were failing against a pre-v0.22.0 file-format - contract on a clean tree) — closes backlog item `[6258]`, now a one-line - closed stub in `BACKLOG.md`. New smoke suite: - `meta/superpowers/validation/2026-09-02-count-entries-smoke.zsh` (18 - assertions). Both mandatory suites green: count-entries 18/18, - session-start 27/27 (0 failed). `plugin.json` 0.25.1→0.25.2; patch release, - no behavior change to any command's contract. Plan: - `meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md`. -- **v0.24.0 merged to `main` via PR #26 (`578b0b5`).** - `BACKLOG.md` item headings now carry a permanent 4-hex-char - tag and filing date alongside the display number: - `### <position>. [<tag>] [<YYYY-MM-DD>] <Title>`. `<position>` is - ephemeral (recomputed gap-free, 1..N, every render); `<tag>` is the - permanent identity for cross-references and the grep-before-delete - safety check. Updated: `skills/session-continuity/templates/BACKLOG.md` - and `SKILL.md` (the rule text itself), `commands/primer.md` (minting a - tag+date on new items, resequencing positions on add/remove), - `commands/end-session.md` (heading-parse, backlog-overlay dedup/citation - now by tag), `hooks/session-start.sh` and `REFERENCE.md` (backlog - reminder shows both `position [tag]`). This repo's own - `.session-continuity/BACKLOG.md` backfilled tags+dates on its 6 - remaining items (dates recovered via `git blame`) and closed item 9 - (the item describing this very problem) as resolved. Also closed item - 8 this session (separate PR #25, merged — `~/.claude/hooks/docs-current-check.sh` - had no per-session debounce, causing the repeated `docs-current - reminder` nag; fixed there, outside this repo since that file is - git-excluded/personal). -- **v0.25.0 merged to `main` via PR #27 (`fcdabad`) and released - (tag `v0.25.0`, GitHub release auto-published from the tag).** - Implemented on branch `feat/learnings-generation-hardening` via - subagent-driven-development: all 7 tasks complete, each task-reviewed - (2 fix rounds total: Task 4's fix-burst title privacy redaction, Task - 5's empty-transcript-dir zsh nullglob bug, Task 6's stale Presentation - example, Task 1's smoke-message hash values — 4 fix rounds across 4 - tasks), final whole-branch review clean (**Ready to merge: Yes**, 0 - Critical, 1 Important triaged non-blocking).** Closes the plan's F1-F11: - `learnings-index.sh reindex` now refuses to write unless the regenerated - file is provably intact (was: could truncate `LEARNINGS.md` to 0 bytes - on a missing awk sibling, exit 0); the three `learnings-index-*.awk` - passes are fence-aware and front-matter-safe; `candidate-extract.sh` - distinguishes `mode:"unavailable"` (bad input, silent) from - `mode:"error"` (broken install, surfaces `.detail`) and fixes a - GNU-coreutils staleness-check bug; `candidate-extract.jq`'s 4 heuristics - are retuned against real archived transcripts (replay harness: - `meta/superpowers/validation/2026-09-01-candidate-replay.zsh`) — real - sessions now produce 2-5 genuine candidates instead of heredoc - fragments and 8-candidate overflow warnings; `commands/end-session.md`/ - `learning.md` prose rewired to match, no longer instructing the agent - to hand-derive what the script already computed. **Unplanned but - user-approved mid-task fix:** `hooks/lib/require-script.sh` declared - `local path=...`, colliding with zsh's special `$PATH`-linked `path` - variable — sourcing it directly into a zsh shell (exactly what - `end-session.md`/`learning.md` do) corrupted `$PATH`, broke its - internal `sed` call, and made every command falsely report a healthy - install as version-mismatched. Fixed (renamed to `script_path`), with a - regression test that sources directly into zsh (no `bash -c` wrapper — - the pattern that hid the bug in the pre-existing 7/7-passing suite). - Closed backlog item 7 [b10f] (this plan, now done) and trimmed item - 5 #39 (its `learning.md`/`end-session.md` sub-parts resolved here; - the `agent-active.sh` fallback sub-part stays open, explicitly out of - this plan's scope). Filed new backlog item 7 #40: `overlap()`'s - dedup math in `candidate-extract.jq` is a real (not just synthetic) - asymmetric-Jaccard defect that over-merges distinct retry-bursts whose - titles share the common boilerplate suffix — non-blocking, deferred. - Validation record: `meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md`. -- **v0.25.1 merged to `main` via PR #28 (`a4ce513`) and released - (tag `v0.25.1`).** Bugfix: `hooks/session-start.sh`'s injected backlog - reminder and `skills/session-continuity/REFERENCE.md`'s standing rule - both told Claude to keep each item's `[hex tag]` visible when - summarizing the backlog, but never said to keep the `[YYYY-MM-DD]` - filing date too — a terse summary could drop dates even though the - hook output and `BACKLOG.md` itself always carry them. Both - instructions now require tag and date together. -- **v0.23.0 merged to `main` via PR #24 (`fc481da`).** - Ships candidate extraction + Heuristics A-D - (`hooks/lib/candidate-extract.sh`), the `step-4-agent-active` derivation - (`hooks/lib/agent-active.sh`, retiring `step-4-compute-only`), and - `LEARNINGS.md`'s duplicate-detection/Symptoms-index regeneration - (`hooks/lib/learnings-index.sh`) as scripts instead of prose the agent - re-executed or re-derived by hand each invocation, plus a shared - `CONTRACT_VERSION` skew guard (`hooks/lib/require-script.sh`). - `commands/end-session.md` Steps 2 and 4 and `commands/learning.md` Steps - 4 and 6 now delegate to these scripts. Closed BACKLOG item 5; filed - items 6 (two parked edge cases + doc staleness — the fallback needs a - spec amendment, not a silent patch) and 7 (an unrelated, pre-existing - smoke-test staleness found during final verification). Four new - hermetic smoke suites (32 assertions: 7 require-script + 8 - candidate-extract + 5 agent-active + 12 learnings-index), all green; - full validation suite now 16 `2026-*-smoke.zsh` runners. Static checks - confirmed `step-4-compute-only`/`compute_only` retired with zero - remaining references in `commands/` or `hooks/`, and all four scripts' - degenerate-input behavior (`/dev/null`) matches their documented - contracts. **Residual gap, still open:** this session's own - `/session-continuity:end-session` invocation ran against the still-cached - v0.22.0 plugin build (the merge doesn't hot-reload an installed plugin - cache) — real end-to-end verification of the *new* Step 2/4 delegation - and `learnings-index.sh` wiring still needs a run after - `/session-continuity:update` + `/reload-plugins` picks up v0.23.0. - Spec: `meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md`. -- **v0.22.0 released** — renamed OUTSTANDING_ITEMS.md to BACKLOG.md, added - ROADMAP.md, added /session-continuity:help. PR #23 merged to `main` - (`d2ff918`), tag `v0.22.0` pushed, GitHub Actions `release.yml` ran - clean, [GitHub - Release](https://github.com/talgolan/session-continuity/releases/tag/v0.22.0) - published 2026-08-31, verified `draft:false`/`prerelease:false` via - `gh release view`. Feature branch deleted (local + remote) after merge. -- **v0.19.0 released** — commit `460f507` pushed to `main`, tag `v0.19.0` - pushed, GitHub Actions `release.yml` ran clean (12s), [GitHub - Release](https://github.com/talgolan/session-continuity/releases/tag/v0.19.0) - published 2026-08-30, verified `draft:false`/`prerelease:false` and the - release body via `gh release view`. Full 12-suite smoke run (112 - assertions) rechecked green on the pushed state before tagging. - Bundles three merged PRs plus a retroactive fix, cut as one release. - PR #20 (`216a53c`): closed - item 9 — trimmed `SKILL.md` 248→170 lines, split gate/hook internals, - the decision tree, customization guidance, team-wide rollout, red - flags, and philosophy into new `skills/session-continuity/REFERENCE.md` - (108 lines). PR #21 (`33888d9`): closed item 7 — `gate-common.sh`'s - `gate_scan_staged` converted its last two `[ -z "$x" ] && continue` - spots to `if/fi`. PR #22 (`d7a9470`): closed item 8 — new - `/session-continuity:doctor` command (read-only, five ✓/⚠️ rows: install - mode, hooks registered, all four `.session-continuity/` files present + - primer not stale, `CLAUDE_PLUGIN_ROOT` resolves and not a stale cache, - gate scripts executable); also fixed `PRIVACY.md`/`CONTRIBUTING.md` - still saying "three files" and missing `REFERENCE.md` from the tree. - **Also this session:** closed item 6 by tracing it — the Init-mode - enrichment it described as unreleased was actually already shipped - inside v0.18.0's code (confirmed via `git merge-base --is-ancestor` - against `cd23e09`); it just never got a CHANGELOG bullet, added - retroactively to the `[0.18.0]` section instead of re-releasing - already-shipped code. **Also fixed: the pushed `v0.18.0` tag/release - had been orphaned** — PR #20's squash-merge absorbed a local-only - unpushed commit's diff into `216a53c`, leaving the original commit - (and the tag pointing at it) unreachable from `main`. Re-pointed the - tag (local delete/recreate + `git push origin :refs/tags/v0.18.0` then - a fresh push) to `cd23e09`, the actual ancestor; verified via - `gh release view` that the GitHub Release re-associated correctly. - diverged local history. Not yet released — no version bump. -- **In flight this session (committed on branch - `docs/gate-chain-trap-and-primer-drift-check`, not yet merged/released): - three doc fixes found by reviewing a consuming project's - (architect-workbench) CLAUDE.md "Read first" section.** (1) `SKILL.md` - gained a "Gate mechanics" subsection warning that chaining `git add - <file> && git commit` in one Bash call gets the whole tool call - denied — not just the commit — when a gate fires, silently skipping - the add too, even on retry; fix is two separate Bash calls. (2) - `SKILL.md`'s maintenance rules and `commands/primer.md` Step 4's - item-6 (apply-the-edits) now both say explicitly: before marking an - outstanding item DONE, verify against the actual code (grep/read), - not memory or a commit-subject match alone — generalizes a rule - architect-workbench had hand-rolled per-project (their own MANDATORY - derived-artifact-sync rule, LEARNINGS #14/#15 there) after discovering - `primer.md`'s refresh flow only checked "touched," not "true." - `commands/end-session.md` already had this rigor (its - `appears-DONE`/`still-open`/`manual` evidence-cited classification) — - only the simpler `primer.md` refresh flow was missing it. (3) New - `skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md` — a - verbatim-copy CLAUDE.md section bundling the read-first pointer, the - primer-refresh rule, and both new rules above, so a project doesn't - have to hand-roll this the way architect-workbench did; `SKILL.md`'s - "For team-wide use" section now points at it instead of one inline - quoted line. Not yet released — no version bump. -- **v0.17.0 released** — commit-time content gates. `proven-gate.sh`, - `smoke-gate.sh`, `evidence-gate.sh`, `backend-parity-gate.sh`, - `occurrence-gate.sh`, and `flaky-gate.sh`'s file check all moved from - `PreToolUse` `Write|Edit` hooks to a `Bash(git commit *)` hook — a - file always saves now; only a commit that stages a gated claim - without its required fields (or an escape hatch) gets denied. New - shared `hooks/lib/gate-common.sh` (payload parsing, staged-content - access via `git diff --cached`, decoration-tolerant escape check, - dot-prefixed scratch-file skip). Fixes two false-trigger bugs found - live: the escape line rejected markdown decoration (`> **Gate:** N/A - — …` was denied, only the bare form worked), and a dot-prefixed - scratch file got blocked four times mid-iteration before it was ever - going to be committed. Full hermetic validation suite green (12 - `2026-*-smoke.zsh` suites under `meta/superpowers/validation/`), - shellcheck clean on all six gates plus the new lib. Accepted, - documented limitation: - `git commit -a`/pathspec bypasses the staged-index scan — see - LEARNINGS #14. `plugin.json` 0.16.0→0.17.0, CHANGELOG `[0.17.0]` - entry added. Spec: - `meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md`. - Plan: `meta/superpowers/plans/2026-08-27-commit-time-content-gates.md`. - Merged via PR #17 (`a168e4a`), tag `v0.17.0` pushed, GitHub Release - published. -- **In flight this session (staged, uncommitted): Init-mode enrichment in - `commands/primer.md`.** Three additions to Step 2's fact-gathering + - derivation so a fresh `/session-continuity:primer` init produces a - richer first primer instead of leaving fields for the user to hand-fill: - (1) run the project's test command once during init and seed - `{{TEST_COMMAND_SUMMARY}}` with the parsed count when the run exits 0 - and has a recognizable count (`N pass`/`N passed`/`test result: ok`), - else fall back to the bare command string or `TBD` — never invent a - count; (2) derive `{{MODULES_TABLE}}` from `@module` docblock grep hits - (one row per file) instead of always `TBD`; (3) draft - `{{WORKFLOW_CONVENTIONS}}` by quoting relevant `CLAUDE.md` conventions - under a "Conventions inherited from CLAUDE.md" sub-heading, presented - for confirmation in Step 6 rather than asked cold. Step 6's ask-list - narrowed accordingly (workflow-conventions only asked cold when no - CLAUDE.md draft was produced). Refresh/split/check modes untouched. - Not yet released — no version bump; stage this primer refresh in the - same commit as the `commands/primer.md` change (do not primer-commit - alone). -- **v0.16.0 released** — tag `v0.16.0` pushed, GitHub Release published - 2026-08-22 (verified `draft:false`/`prerelease:false` via `gh release - view`), merged via PR #16 (`1573de2`), plugin.json bumped - 0.15.1→0.16.0 (`10fc553`). Adds real end-to-end timing for - `/session-continuity:end-session`: each step's self-reported timer only - covered its own Bash block, not the gaps between steps (transcript - mining, checklist review), so the multi-minute totals a user actually - experiences were invisible to `performance.log`. A new final step reads - back the invocation's own `step-1-fast-path` timestamp and logs one - real end-to-end `step-4-ritual-complete` duration per invocation. - Live-tested against a scratch repo via `claude --plugin-dir`. - **Considered and dropped:** a companion self-logged "session start - ready" timing for `session-start.sh` — live testing showed Claude - answers with primer content in text only and never issues the trailing - self-log Bash call, so the mechanism doesn't fire; session-start timing - stays hook-only. See CHANGELOG `[0.16.0]`. -- **v0.15.1 released** — commit `df63267` (squash-merged via PR #15), tag - `v0.15.1` pushed, GitHub Actions `release.yml` ran clean, [GitHub - Release](https://github.com/talgolan/session-continuity/releases/tag/v0.15.1) - published 2026-08-17. Verified via `gh run list` + `gh release view`. - **v0.15.0's self-reported performance-logging instrumentation was - completely non-functional as shipped.** All 11 `perf-log.sh` calls - added to `commands/primer.md`/`commands/end-session.md` used the - unbraced `$CLAUDE_PLUGIN_ROOT/...` form inside bash fences — Claude - Code's template substitution only resolves the braced - `${CLAUDE_PLUGIN_ROOT}` form (confirmed live: real invocation failed - every call with "No such file or directory"; `$CLAUDE_PLUGIN_ROOT` is - not exported as a shell env var to an agent-run Bash tool call - either — only Claude Code's own text templating resolves the braced - form, before the model ever sees the command content). The manual - scratch-repo validations during implementation (plan tasks 4, 5, 7) - didn't catch this because they manually `export`ed the variable - themselves, masking the gap. Found and fixed within minutes of the - v0.15.0 release, by actually invoking `/session-continuity:primer` - for real after updating and reloading. The hook-side mechanism - (`hooks.json` → `perf-wrap.sh`) was unaffected — already used the - braced form, and is confirmed working live: real timing entries for - `session-start.sh`, `pre-commit-check.sh`, `flaky-gate.sh`, - `proven-gate.sh`, etc. are already accumulating in this repo's own - `.session-continuity/performance.log` from ordinary use this - session. See CHANGELOG `[0.15.1]`. -- **v0.15.0 released** — commit `c006b2e` (squash-merged via PR #14), tag - `v0.15.0` pushed, GitHub Actions `release.yml` ran clean, [GitHub - Release](https://github.com/talgolan/session-continuity/releases/tag/v0.15.0) - published 2026-08-17. Verified via `gh run list` + `gh release view`. - Per-repo performance logging: every shipped hook invocation (via a new - `hooks/lib/perf-wrap.sh` timing wrapper, routed through `hooks.json`) - and the heavier batched-bash-call operations inside - `/session-continuity:primer` (6 units) and `/session-continuity:end-session` - (5 units) now log timing to `.session-continuity/performance.log` - (auto-gitignored) via a new shared writer, `hooks/lib/perf-log.sh`. - `/session-continuity:learning` intentionally not instrumented — no - batched bash operation to time. Built via brainstorming → spec → plan - → subagent-driven-development (7 tasks, each independently reviewed; - one cross-task fix caught by end-to-end validation — a marker file - that wasn't gitignored, silently defeating `end-session`'s fast path - after first use; one final whole-branch review caught a stray, never - actually reverted out-of-scope edit to this very file from an earlier - fix round). No new command surfaces the log yet — read it directly - with `jq`/`grep`/`bat`. See CHANGELOG `[0.15.0]` and - `meta/superpowers/specs/2026-08-17-performance-logging-design.md`. -- **v0.14.4 released** — commit `cf29867` (squash-merged via PR #13), tag - `v0.14.4` pushed, GitHub Actions `release.yml` ran clean, [GitHub - Release](https://github.com/talgolan/session-continuity/releases/tag/v0.14.4) - published 2026-08-15. Verified via `gh run list` + `gh release view`. - User-reported: `/session-continuity:end-session` took 20+ minutes on a - real session despite v0.14.2's fast path. Diagnosis: the 20 minutes was - round-trip latency (one model turn per Bash call), not compute — - validated the actual jq/grep work on a 4.3MB/238-call transcript at - <0.05s. Three fixes to `commands/end-session.md` + `commands/primer.md`: - (1) explicit single-Bash-call batching at 4 spots that previously spent - one round trip per command/item (fast-path check, outstanding-items - per-item verification, Step 3's fact-gathering, plus Step 2's transcript - extraction); (2) Step 2's jq filter went from unverified "adjust to the - schema" prose to a concrete filter tested against 3 real transcripts, - fixing a real jq gotcha along the way (`split("\n")[0]` → `null` on - `""`, not `""` — crashes the next `gsub`; see LEARNINGS #10); (3) Step - 1's test-count drift check ran the suite 3× unconditionally — now skips - the rerun when no relevant file changed, runs once otherwise, and only - escalates to the 3-run majority vote on disagreement. Also fixed a - majority-vs-unanimity self-contradiction in `end-session.md`'s - restatement of the retry rule. See CHANGELOG `[0.14.4]`. -- **v0.14.3 released** — commit `e197071`, tag `v0.14.3` pushed, GitHub - Actions `release.yml` ran clean, [GitHub Release](https://github.com/talgolan/session-continuity/releases/tag/v0.14.3) - published 2026-08-15. Verified via `gh run watch` + `gh release view`, - and this bullet itself is the first live use of the fix it describes: - fixes the bug this bullet-pattern kept hitting — the primer's "shipped" - → "released" update lagged behind the actual tag/push/release, because - the workaround (bundle the release bullet with a trivial unrelated - change so it isn't a primer-only commit — see commit `c7177b7`) was - never written down. Both v0.14.1 and v0.14.2 sat marked "(pending - release)" after they'd already shipped, corrected in the prior commit. - `skills/session-continuity/SKILL.md`'s primer-only-commit exception list - now names "record a completed tag+push+release immediately, don't defer - it" as its own case. See CHANGELOG `[0.14.3]`. -- **v0.14.2 released** — commit `e1e20c9`, tag `v0.14.2` pushed, GitHub - Actions `release.yml` ran clean, [GitHub Release](https://github.com/talgolan/session-continuity/releases/tag/v0.14.2) - published 2026-08-14. Verified via `gh run list` + `gh release view`. - Two fixes from user-reported friction, not a doc sweep: (1) - `/session-continuity:end-session` had gotten slow — grew 172→493 lines - across its history, and the two biggest additions (v0.12.0's - outstanding-items verification, v0.6.0's four LEARNINGS heuristics) both - pay real per-invocation runtime cost, not just instruction-length cost. - Added a fast path (skip Step 1 entirely when nothing changed since last - close-out), gated per-item verification behind commit-subject token - overlap (untouched items get a cheap `manual` verdict instead of a full - grep/glob check — documented tradeoff: an item resolved without a - matching commit won't be caught until one lands), and merged Step 2's - four separate transcript scans into one combined extraction pass. (2) - Outstanding-items numbering had no explicit "start at 1, never 0" rule - anywhere — hardened both `hooks/session-start.sh`'s injected instruction - and `SKILL.md`'s standing rule to say so directly. See CHANGELOG - `[0.14.2]` for the full list. -- **v0.14.1 released** — commit `9d8df5f`, tag `v0.14.1` pushed, GitHub - Actions `release.yml` ran clean, [GitHub Release](https://github.com/talgolan/session-continuity/releases/tag/v0.14.1) - published 2026-08-13. Verified via `gh release view`, not assumed. Fixes - a real-world regression reported - from a different repo running the installed v0.14.0 plugin: outstanding - items could render as unnumbered prose in chat, because the "always - render as ordered list" rule only ever covered two mechanical code paths - (`session-start.sh`'s raw output, `end-session.md`'s overlay), never a - general behavioral rule. Added one to `SKILL.md` + strengthened the - hook's own injected text. Also fixed: v0.14.0's `docs/` legacy-fallback - removal shipped without re-running the existing hermetic smoke suites — - 3 suites / 4 assertions were failing the whole time on stale - legacy-path fixtures, caught only by the user report, not by the - release process. All 9 smoke suites (112 assertions) now pass. See - LEARNINGS #9 for the process fix. -- **v0.14.0 released** — commit `5a2f3d6`, tag `v0.14.0` pushed, GitHub - Actions `release.yml` ran clean, [GitHub Release](https://github.com/talgolan/session-continuity/releases/tag/v0.14.0) - published with the real CHANGELOG body (not the LEARNINGS #2 - empty-extraction failure). Verified via `gh run list` + `gh release view`, - not assumed. -- **v0.14.0 shipped** — dropped the pre-v0.5.0 `docs/` legacy fallback - entirely (sole current user, no unmigrated install to carry it for). - Removed dual-path detection/fallback from `hooks/session-start.sh`, - `hooks/pre-commit-check.sh`, `hooks/learnings-surface.sh`, - `hooks/occurrence-gate.sh`, `hooks/flaky-gate.sh` (these two were missed - in the first pass — caught by a follow-up compliance check), - `commands/primer.md` (Migrate mode - and Conflict mode deleted; dispatch is now init/split/refresh/check), - `commands/end-session.md`, `commands/learning.md`, - `skills/session-continuity/SKILL.md`, and `PRIVACY.md`. `git grep` for - `docs/SESSION_PRIMER\.md\|docs/LEARNINGS\.md` across `hooks/`, - `commands/`, `skills/` returns zero hits. Resolves the outstanding item - that had this deferred to "a future v1.0.0." Also: full documentation - accuracy sweep across `README.md`, `CONTRIBUTING.md`, `PRIVACY.md`, - `SECURITY.md`, `CLAUDE.md`, `SKILL.md`, and - `meta/administrative/marketplace-submission.md` — these had drifted - since the v0.13.0 `PROJECT_CONTEXT.md` split (undercounted files/commands, - 3 of 7 gate hooks undocumented) and since the marketplace catalog moved - to `talgolan/claude-plugins` (README's install/update commands were - pointing at the wrong repo/name — a real broken-install bug, not just - prose drift). See CHANGELOG `[0.14.0]`'s Fixed section for the full list. - Confirmed no automated doc-accuracy checking exists anywhere on this - machine at the repo level — it does exist globally (`~/.githooks/pre-commit` - + a global Claude Code `Stop` hook) but only checks "was a doc file - touched," never prose accuracy; verified against the real files, not - from memory. -- **v0.13.0 shipped** — split `.session-continuity/SESSION_PRIMER.md` into - volatile (`SESSION_PRIMER.md`) and stable (`PROJECT_CONTEXT.md`) halves, - overriding the prior §6 rejection on explicit request 2026-08-13. Also - shipped this session: LEARNINGS.md gained an auto-generated Symptoms - index and `[[slug]]` cross-references (§4.2/§4.3, same override). Spec: - `meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md`. - Plan: `meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md`. -- **v0.12.3 shipped** (branch `session-start-outstanding-items`, commit pushed, - tag `v0.12.3` pending). SessionStart hook now surfaces outstanding items from - the primer: extracts the "Outstanding items" section, lists the first line of - each numbered item (sub-bullets dropped), and injects into the SessionStart - reminder with an instruction asking which to tackle. When the section is empty - or missing, no block is added — the output remains identical to prior versions. - New hermetic smoke runner - `meta/superpowers/validation/2026-08-12-session-start-smoke.zsh` validates 11 - test cases covering both paths (`.session-continuity/` and legacy `docs/`), - multi-line items, empty sections, and missing sections; all pass. Shellcheck - clean on the modified hook script. Also fixes a pre-existing `grep -c` exit-code - bug: `grep -c` exits 1 when no matches are found (even though it outputs "0"), - so a fallback `|| echo '0'` would output both the grep "0" and the fallback "0", - causing spurious output duplication in the status line. Fixed by using `|| true` - as the fallback and explicit empty-case handling. `plugin.json` 0.12.2→0.12.3, - CHANGELOG entry added. -- **v0.12.2 shipped** (branch `fix/hook-json-escaping`, PR #11, tag `v0.12.2` - pushed, GitHub Release published, live plugin install refreshed and - verified). Fixes `proven-gate.sh` and `smoke-gate.sh` emitting malformed - JSON on deny: a reason string containing a literal `"` broke their - hand-built `printf` JSON, so the block worked but the reason never - parsed — undiagnosable rather than unsafe. Root cause: every existing - per-gate runner asserted with a substring match on `deny`, which passes on - malformed JSON too, so this shipped green. Fix, in order: - 1. New hermetic runner - `meta/superpowers/validation/2026-08-12-hook-json-contract-smoke.zsh` - parses each gate's deny output with a real JSON parser (`python3 -m - json`) instead of substring-matching it, and fails if any - `hooks/*-gate.sh` has no fixture — so a future gate can't skip the - check. Red on landing (4 failures: `proven-gate` + 3 `smoke-gate` - cases), 16/16 green after the fix. - 2. All six gates' `deny()` (not just the two broken ones) now route the - reason through a `json_escape()` helper: backslash-then-quote - escaping, full C0 control-byte range (`0x00`-`0x1F`, not just - `\n\t\r`) folded to a space. `smoke-gate.sh`'s now-redundant - `offender_esc` pre-escape removed. - 3. `.session-continuity/LEARNINGS.md` entry #1 gained a "Second trap" - addendum: a well-formed JSON *shape* isn't the same as parseable - JSON, and a substring assert can't tell the difference. - 4. `plugin.json` 0.12.1→0.12.2, CHANGELOG entry added. - Full validation suite 8 runners / 101 checks green; shellcheck clean on - all six gates. Built via `superpowers:subagent-driven-development` - (fresh implementer + reviewer per task, final whole-branch review on the - most capable model — 1 Minor finding, non-blocking: the new runner's - coverage check verifies gate-name list membership, not fixture - existence, so CHANGELOG/LEARNINGS phrasing slightly overstates what's - machine-enforced). Plan: - `meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md`. -- **v0.12.1 shipped** (branch `fix/smoke-gate-false-positive`). Fixes a - line-level false positive in `hooks/smoke-gate.sh`: the weak-smoke branch - denied any line where `smoke` co-occurred with a weak-word - (`optional`/`deferred`/`after-merge`/`nice-to-have`), even when the weak-word - modified something unrelated in the same sentence or negated it ("smoke is - MANDATORY — never deferred"). Three-part fix: (1) explicit `MANDATORY` - co-occurring with `smoke` on a line passes unconditionally, checked before the - weak-smoke branch; (2) weak-word only disqualifies when adjacent to `smoke` - (`smoke[^.]{0,20}(weak)` or reverse); (3) deny reason echoes the matched line. - Escape hatch, no-smoke branch, plan self-scoping, output contract all - preserved. New hermetic runner - `meta/superpowers/validation/2026-08-06-smoke-gate-smoke.zsh` 13/13; full - validation suite 85/85 green. Diagnosis report lived in the sibling - smoke-test-plugin (`SMOKE_GATE_FALSE_POSITIVE.md`). `plugin.json` 0.12.0→0.12.1. -- **v0.12.0 shipped** (branch `feat/outstanding-items-verification`, commits - `dd59d4a` + `986b22a`). Adds outstanding-items verification to - `/session-continuity:end-session`: Step 1 now verifies each primer outstanding - item against actual repo state (grep/glob/file-exists checks) before the drift - check runs, computing a verdict (`still-open` / `appears-DONE` / `manual`) with - cited evidence. `appears-DONE` candidates route to the existing combined prompt - when drift exists (Case A), or surface as a standing ⚠️ in the Step 3 checklist - when drift-clean (Case D). Removal always requires explicit user confirmation — - a verdict never mutates the primer on its own. Step 3's Outstanding-items row - re-derives post-edit and reports per-item verdicts with inline evidence. - Validation matrix: `meta/superpowers/validation/2026-07-30-outstanding-items-verification.md` - (8 scenarios covering Cases A–D, never-auto-close invariant, edge cases). Pure - prose-skill change; no new files, hooks, or schemas. -- **v0.11.0 shipped** (squash-merged to `main` as `3941f55`, PR #8). Adds 3 more - executable gates, closing the remaining gap the user identified when asked "what - must never be ignored" beyond CLAUDE.md's 4 core rules — 5 memory-logged feedback - rules also demanded gates; 2 (`proven-gate`, `smoke-gate`) already existed, - these 3 close the rest: - - `hooks/evidence-gate.sh` (Write|Edit, spec/plan) — blocks a smoke-mentioning - plan that describes teardown/cleanup without a preserve-before-teardown - safeguard, or a poll/wait loop without a dual-signal (success+failure) - safeguard. Enforces feedback_never_guess_preserve_evidence. - - `hooks/flaky-gate.sh` (Bash `git commit *` + Write|Edit `LEARNINGS.md`) — - blocks calling a failure "flaky"/"transient"/"CDN blip" without a - `Mechanism:` line naming the deterministic cause. Enforces CLAUDE.md rule 1. - - `hooks/backend-parity-gate.sh` (Write|Edit, plan) — blocks a plan that - frames smoke as multi-backend but names fewer than 2 concrete backends - (docker/apple/podman/containerd/colima/kata/lima/orbstack list). Enforces - feedback_smoke_backend_parity. - All 3 follow the proven-gate/occurrence-gate/smoke-gate skeleton exactly: - self-scoped by path, escape hatch `X-gate: N/A — <reason>`, bounded - best-effort JSON decode, `deny()`/silent-allow output contract. Hermetic - smoke runners (`meta/superpowers/validation/2026-07-01-{evidence,flaky, - backend-parity}-gate-smoke.zsh`) 12/13/11 = 36/36 pass; shellcheck clean on - all 3 hook scripts. Wired into `hooks/hooks.json` (evidence-gate + - flaky-gate + backend-parity-gate appended to the Write|Edit block; - flaky-gate also appended to the Bash `git commit *` block alongside - pre-commit-check.sh). `plugin.json` bumped 0.10.0→0.11.0; CHANGELOG.md - entry added. Manual install-and-fire validation of the 3 new hooks completed - before merge. **Deliberately NOT gated by this batch** (per the reinstall- - PATH-binary memory's own admission): a "PATH binary reinstalled" claim — - hooks fire on tool-call payloads (Write/Edit/Bash), not on prose sentences - in Claude's response, so there's no artifact to grep for that claim itself; - would need a different mechanism (e.g. gating on `git commit`/`gh pr merge` - checking a hash match, proposed but not built). -- v0.10.0 shipped, squash-merged to `main` on `feat/change-the-odds-2-3c` (change-the-odds #2 + #3c, one PR). Adds `hooks/occurrence-gate.sh`: a `PreToolUse` Write|Edit gate scoped to `LEARNINGS.md` under `*/.session-continuity/*` or `*/docs/*` that denies an entry recording `Occurrence count: N of M` (N≥2) unless the same content names a non-empty `Invariant:` line (CLAUDE.md rule 4 → executable gate). Escape hatch `Occurrence-gate: N/A — <reason>`. Largest-N-wins coarse scan. Wired as 4th entry in `hooks.json` Write|Edit block. Mirrors `proven-gate.sh` skeleton — sole deviation from the literal plan code: `deny()` is called inside an `if` (not unconditionally) so the trailing `exit 0` stays reachable / shellcheck-clean (matches proven-gate). Hermetic runner `meta/superpowers/validation/2026-06-17-occurrence-gate-smoke.zsh` 12/12; shellcheck clean. Also: `/learning` gains optional `Occurrence count:` + (N≥2) `Invariant:` fields (gate-compliant by construction); new `/session-continuity:spike-check` command (5-question stand-in checklist, proactive complement to proven-gate). Spec + plan: `meta/superpowers/{specs,plans}/2026-06-17-occurrence-counter-and-spike-check*`. -- v0.9.0 shipped (squash-merged to `main` as `9de77fb`, PR #6 closed, tag `v0.9.0` pushed). Adds `hooks/proven-gate.sh`: a `PreToolUse` Write|Edit gate scoped to `*/specs/*.md` + `*/plans/*.md` that denies a "proven/verified/spike conclusive" claim unless the same content carries adjacent `Real path:` + `Stubbed:` fields. Whole-word claim match (`unproven`/`improven`/`confirmed` do not trigger). Escape hatch `Proven-gate: N/A — <reason>`. Hermetic fixture runner (`meta/superpowers/validation/2026-06-17-proven-gate-smoke.zsh`) 12/12; shellcheck clean. Wired as 3rd entry in `hooks.json` Write|Edit block. Mirrors `smoke-gate.sh` skeleton; sole deviation is the word-boundary match. Spec + plan: `meta/superpowers/{specs,plans}/2026-06-17-proven-gate*`. -- v0.8.0 shipped: two fire-before-action gates (`learnings-surface.sh`, `smoke-gate.sh`) + `/learning` optional Trigger field. -- v0.7.0 shipped (commit `9172667` on `main`, tag `v0.7.0` pushed). Bounds `/session-continuity:end-session` prompt count to ≤2 in the common case: merges Step 1's overlay+outstanding-items prompts into a single combined ask, batches Step 2 candidate confirmation into one prompt instead of looping per-candidate. Adds Step 4 terminal sign-off (`✅ Session complete. Safe to close.`) so the user is never left ambiguous after invoking an explicit close-out. Pure prose-skill change; no new files, hooks, or schemas. See v0.7.0 CHANGELOG entry. -- v0.6.0 shipped (merged to `main` as `7bc25c3`, tag `v0.6.0` pushed; PR #1 closed). Adds the §1 outstanding-items overlay and §5 four-heuristic LEARNINGS candidate surfacing to `/session-continuity:end-session`. Pure prose-skill addition; no new files, hooks, or schemas. See the v0.6.0 CHANGELOG entry for the full diff. -- New project-local `CLAUDE.md` redirects superpowers skills' default `docs/superpowers/{specs,plans}/` paths to `meta/superpowers/`, matching the v0.3 layout. Added after the brainstorming-skill default re-introduced the duplicate `docs/superpowers/` directory. -- v0.5.1 (commit `f5013e1`) shipped quick-win refinements: drop the mtime drift check, 3× test-flake retry, `git log <last-primer>..HEAD` candidate surfacing, hardened `learning` numbering, and a 4-line `SessionStart` status block. -- v0.5.0 (commit `aff74c3`) relocated the two files from `docs/` to `.session-continuity/` with auto-migration support. -- Three slash commands are stable (`primer`, `learning`, `end-session`). -- `hooks/hooks.json` uses `if: "Bash(git commit *)"` to scope the `PreToolUse` hook; it does not fire on every Bash call. -- No `.claude-plugin/marketplace.json` in this repo — the marketplace catalog moved to `talgolan/claude-plugins`; installable via `/plugin marketplace add talgolan/claude-plugins` + `/plugin install session-continuity@talgolan`. -- `.session-continuity/` holds `SESSION_PRIMER.md`, `PROJECT_CONTEXT.md` (new in v0.13.0), `ROADMAP.md` (new in v0.22.0), and `LEARNINGS.md`. The work queue is GitHub Issues labeled `backlog` (v0.29.0; previously `BACKLOG.md`, itself renamed from `OUTSTANDING_ITEMS.md` in v0.22.0). Dev artifacts (marketplace-submission notes, specs, plans, recommendation docs) live under `meta/`. -- No known open bugs; outstanding items are feature-level. - -**Current `git log --oneline -5` (primary branch):** - -``` -de381a8 feat: primer-detect.sh/.jq, scripting /session-continuity:primer's Step 1 dispatch (Phase 6 sub-project A) (#52) -8dfd9c9 refactor: end-session's overlap gate is now hooks/lib/token-overlap.sh/.jq (#51) -ddaccca Merge pull request #50 from talgolan/determinism-phase-4-step3-checklist -40f5496 fix(docs): inline sign-off strings in end-session fallback path -b7b82f3 docs: Phase 4 doc pointers, changelog, and version bump for the checklist script +## Boot order +1. `.session-continuity/PROJECT_CONTEXT.md` +2. `.session-continuity/LEARNINGS.md` (grep on surprise) +3. engrim context / recall (required) +4. graphify query when the question is about code structure +5. This file — Mid-flight + Confirm +6. `/session-continuity:backlog` for the deferred queue + +## Mid-flight +- Finish/merge #62 thin hard-template SESSION_PRIMER (this branch `feat/primer-thin-hard-template`) — plan `meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md` +- Determinism Phase 6 on #43 — C/E still open (deprioritized); A/B/D shipped in 0.32–0.34 +- #38 docguard generalization still open (githooks side unmerged; this-repo design already landed) + +## Confirm +```bash +bash hooks/lib/primer-validate.sh .session-continuity/SESSION_PRIMER.md +zsh meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-primer-freshness-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-session-start-peers-smoke.zsh ``` -Regenerate this block whenever you commit — see -`.session-continuity/PROJECT_CONTEXT.md`'s "Maintenance" section. +## Peers +- engrim: required — status unknown until probed +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog` diff --git a/CHANGELOG.md b/CHANGELOG.md index 70f4644..6364e31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.36.0] — 2026-09-09 + +### Changed +- **Thin hard-template `SESSION_PRIMER`.** Boot order / Mid-flight / Confirm / + Peers only; validator + peer probes; SessionStart/doctor hard-incomplete + without local engrim and a committed `graphify-out/graph.json`. Fat primers + slim-migrate via `/session-continuity:primer`. Banlist drops embedded + `git log --oneline` regen blocks. Dogfood primer + PRIVACY/README peer + disclosure shipped with this release. + ## [0.35.0] — 2026-09-09 ### Added diff --git a/PRIVACY.md b/PRIVACY.md index 496a724..ddfed9d 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -2,11 +2,11 @@ **Plugin:** `session-continuity` **Maintainer:** Tal Golan ([github.com/talgolan](https://github.com/talgolan)) -**Last updated:** 2026-09-07 +**Last updated:** 2026-09-09 ## Short version -This plugin does not collect analytics or send data to the maintainer. Durable memory stays in your git repository. The work queue is GitHub Issues labeled `backlog` on that same repository: filing an issue sends its title and body to GitHub; SessionStart and `/session-continuity:backlog` read them back with authenticated `gh`. There is also one weekly unauthenticated version-check GET. Public repository means public issues. +This plugin does not collect analytics or send data to the maintainer. Durable memory stays in your git repository. Session boot also expects local engrim memory and a committed `graphify-out/graph.json` as required peers (neither leaves your machine via this plugin). The work queue is GitHub Issues labeled `backlog` on that same repository: filing an issue sends its title and body to GitHub; SessionStart and `/session-continuity:backlog` read them back with authenticated `gh`. There is also one weekly unauthenticated version-check GET. Public repository means public issues. ## What data the plugin handles diff --git a/README.md b/README.md index 48744f7..33e42cd 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ From inside Claude Code, add the `talgolan` catalog as a plugin marketplace, the Run `/reload-plugins` once the install finishes. Once the plugin is live on the official Anthropic marketplace (`claude-plugins-official`), you'll also be able to discover it via `/plugin` → **Discover**; until then, the two-step sequence above works on any recent Claude Code install. +Required peers for a green `/session-continuity:doctor`: local `engrim` on PATH, and a committed non-empty `graphify-out/graph.json` (install order: primer → graphify commit → engrim → re-doctor). + ## The four files, plus the queue Everything else is machinery around these documents. Each has a different update contract. @@ -71,10 +73,10 @@ One command, six behaviors, dispatched on the repo's current state: - **No primer yet** → copies the templates into `.session-continuity/`, fills every placeholder it can derive (project name, latest commits, working directory, test command), asks you for the rest, files named follow-ups as GitHub Issues labeled `backlog` when `gh` is authenticated for the origin's host (github.com or a GitHub Enterprise Server instance), and stages four files. Any field you skip becomes `TBD` rather than a leftover `{{PLACEHOLDER}}`. - **Primer exists but not yet split** → partitions its stable sections (layout, conventions, module table, "where to look for what") into a new `.session-continuity/PROJECT_CONTEXT.md`, leaving the primer with only the volatile shortlist. One-time content move, no file move. - **Primer has an inline Outstanding items section, or a leftover `OUTSTANDING_ITEMS.md` / `BACKLOG.md`** → migrates that markdown queue to GitHub Issues labeled `backlog` when `gh` is authenticated for the origin's host, then deletes the file. Without that, the file is left as a fossil and `doctor` warns. -- **Primer exists but drifted** → regenerates the `git log --oneline -5` block, re-runs the primer's test commands (retrying flaky suites up to three times so a single bad sample doesn't cry wolf), surfaces every commit since the last refresh as a candidate, and prompts you for backlog changes before staging. +- **Primer exists but drifted** → rewrites Mid-flight + Confirm only (thin hard-template), re-runs Confirm commands, validates shape via `primer-validate.sh`, surfaces commits since the last primer touch as candidates, and prompts you for backlog changes before staging. Peers (engrim + committed `graphify-out/graph.json`) stay doctor/SessionStart concerns — refresh does not embed a git-log dump. - **Primer current** → reports a four-line status (HEAD, last refresh, backlog count, learnings count) and exits without touching anything. -Drift is detected by diffing the stored `git log` block against reality, not by file mtime, because formatters and save-on-blur bump mtime without changing content. +Drift is detected by `primer-freshness.sh` (substantive commits after the last primer touch, with basename ignores for README/CHANGELOG/LICENSE), not by an embedded git-log block or file mtime. ### `/session-continuity:learning` @@ -84,7 +86,7 @@ Appends a properly formatted entry. It prompts for the recipe fields, lets you p The close-out ritual, bounded to at most two prompts in the common case: -1. **Refresh the primer**, but only if it actually drifted. If the `git log` block already matches reality, this step checks whether any backlog item now looks resolved (verified against actual code, never guessed) — if so, it offers a lightweight prompt to close it; otherwise it's a silent no-op. +1. **Refresh the primer**, but only if it actually drifted (`STALE=1` from `primer-freshness.sh`). If freshness is current, this step checks whether any backlog item now looks resolved (verified against actual code, never guessed) — if so, it offers a lightweight prompt to close it; otherwise it's a silent no-op. 2. **Mine the session for learnings.** It reads the session transcript (falling back to the live context window when the transcript isn't reachable) and runs four deterministic detectors: a *retry burst* (the same command run three or more times), a *revert/reset* (hard reset, checkout, revert, or `rm -rf` on a tracked file), an *error recurrence* (the same normalized error three or more times across 15+ minutes), and a *fix burst* (a `fix:` commit preceded by a long investigation). Candidates are pre-drafted into full LEARNINGS entries and presented in one batch for a single confirm. 3. **Print a state checklist.** Staged, unstaged, untracked, and unpushed are each enumerated file by file, with a suggested commit message and a terminal sign-off so you know the ritual is done. @@ -158,7 +160,7 @@ Detects no primer exists, copies templates into `.session-continuity/`, fills de /session-continuity:primer ``` -Detects drift, regenerates the `git log` block, prompts for backlog updates, and stages the refreshed primer. Commit it alongside your substantive change, not in a primer-only commit. +Detects drift, refreshes Mid-flight + Confirm (and validates the thin hard-template), prompts for backlog updates, and stages the refreshed primer. Commit it alongside your substantive change, not in a primer-only commit. **After a painful bug (15+ min to diagnose):** diff --git a/commands/doctor.md b/commands/doctor.md index 41c87e3..10f6b36 100644 --- a/commands/doctor.md +++ b/commands/doctor.md @@ -10,7 +10,7 @@ You are responding to the `/session-continuity:doctor` slash command. ## Step 1 — Gather -Run everything in **one Bash call**, timed: +Run everything in **one Bash call**, timed. Gate each new helper through `require_script` at `CONTRACT_VERSION=1` before relying on its output (same pattern as `primer-status.sh` in `/session-continuity:primer`): ```bash _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") @@ -54,8 +54,42 @@ if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/hooks/lib/bac bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" --count . fi -echo "--- current git log (compare against primer's block) ---" -git log --oneline -5 +if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then + # shellcheck disable=SC1091 + source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" +fi + +echo "--- primer validate ---" +if [ -f .session-continuity/SESSION_PRIMER.md ] && [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" .session-continuity/SESSION_PRIMER.md \ + && echo "PRIMER_VALIDATE=ok" || echo "PRIMER_VALIDATE=fail" + else + echo "⚠️ $SC_REQUIRE_SCRIPT_MSG" + echo "PRIMER_VALIDATE=fail" + fi +fi + +echo "--- peer probes ---" +if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/peer-probes.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/peer-probes.sh" . + else + echo "⚠️ $SC_REQUIRE_SCRIPT_MSG" + echo "ENGRIM=?" + echo "GRAPHIFY=?" + fi +fi + +echo "--- primer freshness ---" +if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-freshness.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-freshness.sh" . + else + echo "⚠️ $SC_REQUIRE_SCRIPT_MSG" + echo "STALE=?" + fi +fi _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") @@ -74,7 +108,12 @@ Work through the six rows below using the output above. Never invent a result fo - Plugin mode: ✓ if `HOOKS_JSON_EXISTS=1` (Claude Code auto-wires this when the plugin is enabled — this is a sanity check that the install isn't partial/corrupted, not proof the user configured anything). ⚠️ if `HOOKS_JSON_EXISTS=0` — the plugin directory is missing `hooks/hooks.json`; reinstalling the plugin is the fix. - Vendored mode: grep the `.claude/settings.json` content captured above for the hook script names (`session-start.sh`, `learnings-surface.sh`, etc.). ✓ if at least `session-start.sh` and `learnings-surface.sh` appear (the two hooks a vendored install needs most — the primer reminder and the retrieval hook). ⚠️ listing which expected hook names are absent, with a pointer to `SKILL.md`'s hooks section for the entries to copy in. -3. **Four `.session-continuity/` files exist; primer not stale.** ✓/⚠️ per file from the `EXISTS`/`MISSING` lines (`SESSION_PRIMER.md`, `PROJECT_CONTEXT.md`, `ROADMAP.md`, `LEARNINGS.md`). `BACKLOG.md=FOSSIL` is a leftover markdown queue — ⚠️ "fossil BACKLOG.md; run `/session-continuity:primer` to migrate to GitHub Issues if `gh` is authenticated for the origin's host." For `SESSION_PRIMER.md` specifically, if it exists, also compare its own `git log --oneline -5` block (read the file) against the `git log --oneline -5` output captured above — mismatch means ⚠️ stale, "run `/session-continuity:primer` to refresh." This is the only file with an objective staleness signal in this repo; the other three don't get a staleness check here, only an existence check. +3. **Four `.session-continuity/` files; primer shape, peers, freshness.** ✓/⚠️/✗ from the gather lines — never invent a signal that wasn't printed. + - Existence: ✓/⚠️ per file from the `EXISTS`/`MISSING` lines (`SESSION_PRIMER.md`, `PROJECT_CONTEXT.md`, `ROADMAP.md`, `LEARNINGS.md`). `BACKLOG.md=FOSSIL` is a leftover markdown queue — ⚠️ "fossil BACKLOG.md; run `/session-continuity:primer` to migrate to GitHub Issues if `gh` is authenticated for the origin's host." + - Shape: if `SESSION_PRIMER.md` exists and `PRIMER_VALIDATE=fail` → ✗ hard fail (shape). Cite any `INVALID:` lines from the validate helper stderr that appeared in the gather output. Fix: rewrite Mid-flight/Confirm to the thin hard-template and re-run `/session-continuity:primer`, then re-doctor. + - Peers: if `ENGRIM` or `GRAPHIFY` is present and ≠ `ok` → ✗ hard fail (peers). Notes must include the install order: primer → graphify (commit `graphify-out/graph.json`) → engrim → re-doctor. Also note: commit/rebuild `graphify-out/graph.json`, ensure `engrim` is on PATH. Do not treat missing `ENGRIM=`/`GRAPHIFY=` lines (probe skipped) as a peer failure — report `?` for that sub-check. + - Freshness: `STALE=1` → ⚠️ only ("primer stale vs substantive commits — run `/session-continuity:primer` to refresh"). `STALE=0` is fine. `STALE=?` → report `?`, do not invent stale. Do **not** compare any embedded git-log block; freshness comes only from `primer-freshness.sh`. + - Marker precedence for this row: any ✗ (shape or peers) wins over ⚠️; list every distinct problem (missing files, shape, peers, fossil, stale) — do not summarize to a single cause. 4. **`CLAUDE_PLUGIN_ROOT` resolves and isn't stale.** Skip this row entirely in vendored mode (nothing to check). In plugin mode: ✓ if `ROOT_EXISTS=1`. Then check staleness — from the `ls "$CACHE_PARENT"` output, if it lists sibling version directories, compare the resolved version (parsed from `plugin.json` above) against the highest version number listed. If a newer one exists: ⚠️ "resolved root is v`<old>`, but v`<new>` is already installed in the cache — this session started before the update landed; restart the session to pick it up." If they match, or the cache-parent listing wasn't available (different install layout), ✓ with a note that the check was skipped when applicable — don't fail the row over a probe that simply didn't apply. @@ -90,7 +129,7 @@ Emit the report as a table, same convention as `/session-continuity:end-session` |---|---|---| | Install mode | ✓ | "Plugin vX.Y.Z at `<path>`" OR "Vendored (CLAUDE_PLUGIN_ROOT unresolved)" | | Hooks registered | ✓ / ⚠️ | plugin: "hooks.json present" OR "⚠️ hooks/hooks.json missing — reinstall the plugin" · vendored: "session-start.sh + learnings-surface.sh found in .claude/settings.json" OR "⚠️ missing: `<names>` — see SKILL.md's hooks section" | -| .session-continuity/ files | ✓ / ⚠️ | "All four present, primer current" OR "⚠️ missing: `<names>`" OR "⚠️ primer stale — run /session-continuity:primer" OR "⚠️ fossil BACKLOG.md" | +| .session-continuity/ files | ✓ / ⚠️ / ✗ | "All four present; primer shape ok; peers ok; freshness current" OR "✗ primer shape — `PRIMER_VALIDATE=fail`" OR "✗ peers — `ENGRIM`/`GRAPHIFY` not ok; install order: primer → graphify (commit `graphify-out/graph.json`) → engrim → re-doctor" OR "⚠️ missing: `<names>`" OR "⚠️ primer stale (`STALE=1`) — run /session-continuity:primer" OR "⚠️ fossil BACKLOG.md" | | CLAUDE_PLUGIN_ROOT | ✓ / ⚠️ / (skipped) | "vX.Y.Z, matches latest cached" OR "⚠️ resolved to vX.Y.Z, but vX.Y.Z+1 is cached — restart the session" OR "skipped (vendored mode)" | | Gate scripts executable | ✓ / ⚠️ / (skipped) | "All N gate scripts executable" OR "⚠️ not executable: `chmod +x <path>`, `chmod +x <path>`" OR "skipped (vendored mode)" | | GitHub backlog | ✓ / ⚠️ | "N open issues labeled backlog" OR "⚠️ gh/auth/origin/helper — queue inactive. Filing an issue sends title+body to GitHub (public repo → public issues)." | @@ -98,5 +137,7 @@ Emit the report as a table, same convention as `/session-continuity:end-session` ## Notes - **Never mutates anything.** No file writes, no `git add`, no `chmod` run on the user's behalf — every fix is a command printed for the user to run themselves. -- **Fail soft on probes that don't apply**, not on the row as a whole. A probe that was skipped because it doesn't apply to this install mode is not the same as a probe that ran and found a problem — don't conflate a `?`/skip with a ⚠️. +- **Fail soft on probes that don't apply**, not on the row as a whole. A probe that was skipped because it doesn't apply to this install mode is not the same as a probe that ran and found a problem — don't conflate a `?`/skip with a ⚠️ or ✗. - **Never invent a version number, path, or file list.** Every value in the report must trace back to a literal line in Step 1's output. +- **Peer hard-fail install order.** When `ENGRIM` or `GRAPHIFY` ≠ ok: primer → graphify (commit `graphify-out/graph.json`) → engrim → re-doctor. Rebuild/commit the graph if missing; put `engrim` on PATH. +- **Freshness is `STALE=` only.** Do not treat an embedded git log in the primer as a staleness signal — that compare is retired. diff --git a/commands/end-session.md b/commands/end-session.md index c1b0081..23a75da 100644 --- a/commands/end-session.md +++ b/commands/end-session.md @@ -23,11 +23,11 @@ If either is missing, tell the user: Exit. Do not proceed. -## Step 1 — Refresh the primer (drift-gated) +## Step 1 — Refresh the primer (freshness-gated) Before prompting the user for anything, check the fast path below. If it doesn't fire, verify the primer's outstanding items against code, then run a -drift check. The goal: if the primer is already in sync with the repo, do +freshness check. The goal: if the primer is already in sync with the repo, do nothing and record a no-op. Only enter the refresh flow when something actually changed. @@ -50,7 +50,7 @@ bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --nam If `git status --porcelain` is empty AND `<last-primer-commit>` equals `HEAD` (no commits have landed since the primer was last touched), skip the -rest of Step 1 entirely — no drift check, no backlog verification, +rest of Step 1 entirely — no freshness check, no backlog verification, no git-log recomputation. Nothing in the repo has changed since the last close-out, so no per-item re-check could turn up anything new. Step 3's Primer refresh row reads ✓ "Primer already current (no-op)"; the @@ -174,14 +174,14 @@ gate the plugin enforces on "proven" claims elsewhere. **Routing `appears-DONE` candidates.** These are close-candidates — **never auto-removed**. -- **When the drift check below enters the refresh flow** (drift detected): +- **When the freshness check below enters the refresh flow** (`STALE=1` or `STALE=?`): append every `appears-DONE` item to the existing backlog overlay candidate list, so it surfaces at Step 1's single combined prompt. One reply closes it. Cite the evidence beside the candidate. -- **When the primer is drift-clean** (refresh flow skipped): if at least one - `appears-DONE` item was found, run the **drift-clean close-candidate prompt** +- **When the primer is freshness-clean** (`STALE=0`, refresh flow skipped): if at least one + `appears-DONE` item was found, run the **freshness-clean close-candidate prompt** below instead of the refresh flow. If zero `appears-DONE` items were found, - no prompt fires at all — the "drift-clean + zero candidates = zero prompts" + no prompt fires at all — the "freshness-clean + zero candidates = zero prompts" guarantee holds. Removal of any item always requires explicit user confirmation. A verdict never @@ -211,73 +211,48 @@ Skip this entirely when there were zero open items to classify (the file is absent; Step 3 treats a missing path under `backlog_mode="normal"` as zero tracked items — see `hooks/lib/checklist-assemble.sh`'s contract). -### Drift check (silent — no user prompt) +### Freshness check (silent — no user prompt) -Read `.session-continuity/SESSION_PRIMER.md` and compare its `git log --oneline -5` block to the actual output of `git log --oneline -5` against the primary branch. Two outcomes: - -- **Block matches.** Treat the primer as current — no git-log regeneration, no test-count re-check, no refresh flow. Then check the Backlog verification results computed above: - - **Zero `appears-DONE` items.** Skip the rest of Step 1. In Step 3's checklist, record the Primer refresh row as ✓ "Primer already current (no-op)". - - **≥1 `appears-DONE` item.** Run the drift-clean close-candidate prompt below instead of skipping Step 1. -- **Block differs** (any line differs — subjects, hashes, or ordering). Enter the refresh flow below. - -Run the shared test-count rerun script — the same one `commands/primer.md` -Step 4 item 3 calls, so both commands stay in lockstep — timed: +Gate Step 1's primer rewrite with `primer-freshness.sh` (not an embedded +git-log block — those are banlisted). Timed, via `require_script`: ```bash _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") -LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" -if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" 1; then - RERUN_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" . "$LAST_PRIMER_COMMIT" 2>&1)" - RERUN_STATUS=$? +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-freshness.sh" 1; then + FRESH_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-freshness.sh" . 2>&1)" + FRESH_STATUS=0 else - RERUN_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" - RERUN_STATUS=1 + FRESH_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" + FRESH_STATUS=1 fi _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") -RETRIES=$(printf '%s' "$RERUN_OUTPUT" | awk -F= '/^RETRIES=/{print $2}') -echo "$RERUN_OUTPUT" -echo "RERUN_STATUS=$RERUN_STATUS" +bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-1-freshness --duration="$_PERF_DURATION" +echo "$FRESH_OUTPUT" +echo "FRESH_STATUS=$FRESH_STATUS" ``` -Run this as the **same Bash tool call** as the pre-existing perf-log block a -few lines below ("At the end of this Bash call (whichever branch above -ran):", unmodified by this task) — that block reads `$_PERF_DURATION` and -`$RETRIES` from this one. A separate tool invocation would see both empty -and silently log a wrong duration/retries. - -**If `RERUN_STATUS` is nonzero, or `$RERUN_OUTPUT` has no `MODE=` line:** -report `$RERUN_OUTPUT` to the user and fall back to `TBD` for this axis — -never fabricate a drift verdict from a failed script. - -**Otherwise**, report per `MODE`: -- `skip` — no relevant file changed; say nothing (matches today's silent - skip). -- `no-command` — no test command recorded; nothing to check. -- `no-count`, `RETRIES=0`, `DRIFT=0` always — nothing recorded yet to - compare against; no report needed on this axis. -- `run` with `DRIFT=0` — the count held (whether on the first try or after - majority-vote confirmation); no report needed. -- `run` with `DRIFT=1` — report drift using `PINNED_COUNT` (`"Test count - drifted: recorded <RECORDED_COUNT>, now <PINNED_COUNT> (confirmed over - <RETRIES>+1 runs)."`). -- `run` with `SPREAD=1` — report instability using the comma-joined - `OBSERVED` values (`"Test suite is unstable: saw <OBSERVED, /-joined> - across 3 runs."`), not a drift verdict. -- `run` with `UNPARSEABLE=1` and no `PINNED_COUNT` — report `"Test command - produced no parseable count after <RETRIES>+1 attempts."` - -At the end of this Bash call (whichever branch above ran): -```bash -bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=end-session --step=step-1-drift-test-rerun --duration="$_PERF_DURATION" --retries="$RETRIES" -``` -using the same `_PERF_START`/`_PERF_END`/`_PERF_DURATION` pattern used -elsewhere in this file, captured around this whole check. +Interpret `STALE=` from `$FRESH_OUTPUT` (treat require failure / missing +`STALE=` as `STALE=?`): + +- **`STALE=0`.** Treat the primer as current — no Mid-flight/Confirm + rewrite, no refresh flow. Then check the Backlog verification results + computed above: + - **Zero `appears-DONE` items.** Skip the rest of Step 1. In Step 3's + checklist, record the Primer refresh row as ✓ "Primer already current + (no-op)". + - **≥1 `appears-DONE` item.** Run the freshness-clean close-candidate + prompt below instead of skipping Step 1. +- **`STALE=1`.** Enter the refresh flow below. +- **`STALE=?`.** Report the freshness probe as inconclusive, then enter + the refresh flow (conservative — better to refresh than silently skip). -### Drift-clean close-candidate prompt (runs only when drift is clean AND ≥1 `appears-DONE` item) +### Freshness-clean close-candidate prompt (runs only when `STALE=0` AND ≥1 `appears-DONE` item) -A lighter-weight alternative to the refresh flow below — no git-log regeneration, no test-count re-check, no commit-subject overlay matching (there is no "commits since last refresh" list to match against when nothing drifted). +A lighter-weight alternative to the refresh flow below — no Mid-flight/Confirm +rewrite, no Confirm re-run, no commit-subject overlay matching (there is no +"commits since last refresh" list to match against when freshness is clean). 1. Render the `appears-DONE` items as the same markdown ordered list format used by the refresh flow's overlay (`#N` as identity, citing the code evidence). 2. Before rendering the question below, log a prompt-shown marker (isolates the human-response wait from ritual compute time — see Step 4): @@ -286,7 +261,7 @@ A lighter-weight alternative to the refresh flow below — no git-log regenerati bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" mark --source=command --name=end-session --step=step-1-prompt-shown ``` - Then ask a close-only question, scoped narrower than the refresh flow's combined prompt since there are no commit subjects or free-form drift to fold in: + Then ask a close-only question, scoped narrower than the refresh flow's combined prompt since there are no commit subjects or free-form Mid-flight edits to fold in: > "Backlog — N appears-DONE (see list). Close any, or leave as-is?" 3. **Wait for the answer before continuing.** Same refusal rule as the refresh flow: never close an item without explicit confirmation. Once the answer arrives, log the wait duration: @@ -297,14 +272,31 @@ A lighter-weight alternative to the refresh flow below — no git-log regenerati 4. If the user closes any items, `gh issue close N --reason completed` for each confirmed `#N`. Do not edit a markdown backlog file. Step 3's Primer refresh row reads ✓ "Primer updated (outstanding item(s) closed)". 5. If the user declines, skip the rest of Step 1. Step 3's Primer refresh row reads ✓ "Primer already current (no-op)", and the still-open `appears-DONE` item(s) surface again as a ⚠️ in the Backlog row (same standing-reminder behavior as before — it'll be offered again next session). -### Refresh flow (runs only when drift was detected) +### Refresh flow (runs when `STALE=1` or `STALE=?`) -Follow the logic in **Step 5 of `commands/primer.md`** (refresh mode): +Thin Mid-flight/Confirm refresh — follow **Step 4 of `commands/primer.md`** +(refresh mode), then re-run Confirm and validate. Do **not** regenerate +git-log blocks, test-count tables, or treat the primer as a changelog. + +1. Rewrite Mid-flight (≤5 bullets) and Confirm (≤5 counted commands). Update Peers status lines if needed (agent-maintained on refresh — not SessionStart). +2. **Re-run the Confirm commands** from the primer's Confirm fence (same shell, timed). Report pass/fail per command. Failed Confirm commands do not auto-edit Mid-flight — surface them to the user in the combined prompt below. +3. **Validate before staging:** + + ```bash + source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" .session-continuity/SESSION_PRIMER.md + else + echo "$SC_REQUIRE_SCRIPT_MSG" >&2 + false + fi + ``` -1. Regenerate the `git log --oneline -5` block with current output. -2. If `MODE=run` and `DRIFT=1` (per the test-count rerun script's output - above), update the test-counts section to `PINNED_COUNT`. -3. **Surface commits since the last primer refresh, with backlog overlay.** Reuse the commit list already computed in the Backlog verification section above (`git log <last-primer-commit>..HEAD --oneline`) — do not recompute it. Present the subject list as candidate prompts. + **On failure: stop.** Show stderr. Do not stage a failing primer. If + failure is fat-class or Outstanding/BACKLOG fossils remain, tell the + user to run `/session-continuity:primer` (slim-migrate) before finishing + end-session. +4. **Surface commits since the last primer refresh, with backlog overlay.** Reuse the commit list already computed in the Backlog verification section above (`git log <last-primer-commit>..HEAD --oneline`) — do not recompute it. Present the subject list as candidate prompts. Then look up the **backlog overlay** for each subject: filter `.session-continuity/.end-session-overlap.tsv` (computed once in the @@ -330,7 +322,7 @@ Follow the logic in **Step 5 of `commands/primer.md`** (refresh mode): **Refusal.** Never close an outstanding item without explicit user confirmation. The overlay is a candidate list, not an auto-close. **Skip conditions.** If `.session-continuity/.end-session-issues.txt` is `No open backlog issues.` or the GitHub-unavailable warning, skip the overlay silently — the raw subject list still appears. -4. **Single combined prompt.** After printing the subject list (and overlay block if any), log a prompt-shown marker (same mechanism as the drift-clean prompt above — isolates human-response wait from ritual compute time, see Step 4): +5. **Single combined prompt.** After printing the subject list (and overlay block if any), log a prompt-shown marker (same mechanism as the freshness-clean prompt above — isolates human-response wait from ritual compute time, see Step 4): ```bash bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" mark --source=command --name=end-session --step=step-1-prompt-shown @@ -345,8 +337,8 @@ Follow the logic in **Step 5 of `commands/primer.md`** (refresh mode): ```bash bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" since --source=command --name=end-session --mark-step=step-1-prompt-shown --emit-step=step-1-prompt-wait ``` -5. Apply the edits the user specified. If they asked to close issues, `gh issue close N --reason completed` for each confirmed `#N` after checking the claim against the code. If they asked to file new follow-ups, `gh issue create --label backlog --title "..." --body "..."`. If the user replied "no changes" (or similar), skip this step. -6. Stage the updated primer, and `PROJECT_CONTEXT.md` too if it has +6. Apply the edits the user specified. If they asked to close issues, `gh issue close N --reason completed` for each confirmed `#N` after checking the claim against the code. If they asked to file new follow-ups, `gh issue create --label backlog --title "..." --body "..."`. If the user replied "no changes" (or similar), skip this step. Re-validate with `primer-validate.sh` if Mid-flight/Confirm changed again after the prompt. +7. Stage the updated primer, and `PROJECT_CONTEXT.md` too if it has unstaged changes (e.g. the session edited repo layout / conventions): ```bash @@ -561,7 +553,7 @@ echo "$CHECKLIST" - `BACKLOG_MODE` / `BACKLOG_FASTPATH_COUNT`: `"fast-path"` + the fast path's `<fast-path-backlog-count>` when Step 1's fast path fired; otherwise whichever of `none`/`unavailable`/`not-migrated`/`normal` Step 1's Backlog verification section landed on (its own skip conditions already tell you which). - `TSV`: leave as computed above (empty string unless the in-repo scratch file existed and was copied out before deletion) — never override it by hand. -- `PRIMER`: `"refreshed"` if the refresh flow ran and staged the primer, `"closed"` if only the drift-clean close-candidate prompt ran and closed item(s), `"current"` if Step 1 was a no-op (fast path or drift-clean-zero-candidates). +- `PRIMER`: `"refreshed"` if the refresh flow ran and staged the primer, `"closed"` if only the freshness-clean close-candidate prompt ran and closed item(s), `"current"` if Step 1 was a no-op (fast path or freshness-clean-zero-candidates). - `LEARNINGS_JSON`: the accepted drafts from Step 2's capture flow, as `[{"number":N,"title":"..."}]`; `[]` if Step 2 captured nothing. - `COMMIT_SUBJECT_JSON`: `"null"` (the bare word, unquoted) unless staged files exist AND at least one is outside `.session-continuity/` — in that case, a quoted JSON string with your conventional-commit subject (`<type>(<scope>): <subject>`, ≤72 chars), e.g. `'"fix(ci): extract CHANGELOG section with proper awk range"'`. Pick the theme from the most prominent captured learning's title, or the primary code-change theme — same judgment call as before this phase, just handed to the script instead of formatted by hand. @@ -635,10 +627,10 @@ already governs the rest of this design. - **`step-4-ritual-complete` includes human response time, by design.** It is real wall clock from this invocation's first log line to its last, and that necessarily spans however long the user took to answer the Step 1 and Step 2 prompts. `step-4-agent-active` (same block) derives the agent's own active time directly from the transcript, isolating the agent's own processing time. When investigating a slow ritual, compare both numbers before assuming a script regression — a large `step-4-ritual-complete` with a small `step-4-agent-active` means the user was away from the keyboard, not that anything got slower. - **Respect the primer-only-commit rule.** If the user, after seeing the checklist, commits only the primer, the `PreToolUse` hook's nudge still applies — nothing to do here. - **Zero arguments.** If the user passed text after `/session-continuity:end-session`, ignore it — session reflection provides all context needed. -- **Bound the prompt count.** The whole ritual must fit ≤2 user prompts in the common case: one Step 1 prompt (the full combined prompt when drift exists, or the lighter drift-clean close-candidate prompt when drift is clean but `appears-DONE` items exist), one batch confirm in Step 2 (only when candidates surface). Drift-clean + zero candidates = zero prompts; drift-clean + ≥1 candidate = exactly one (lightweight) prompt. Never split Step 1's prompt into two sequential asks. Never loop one-prompt-per-candidate in Step 2. +- **Bound the prompt count.** The whole ritual must fit ≤2 user prompts in the common case: one Step 1 prompt (the full combined prompt when freshness says stale, or the lighter freshness-clean close-candidate prompt when freshness is clean but `appears-DONE` items exist), one batch confirm in Step 2 (only when candidates surface). Freshness-clean + zero candidates = zero prompts; freshness-clean + ≥1 candidate = exactly one (lightweight) prompt. Never split Step 1's prompt into two sequential asks. Never loop one-prompt-per-candidate in Step 2. - **Always sign off.** Step 4's terminal line is non-negotiable — the user invoked an explicit close-out and must not be left ambiguous about whether the ritual is done. - **Backlog verdicts never mutate the primer.** The verification in Step 1 only classifies and reports; an `appears-DONE` item is removed only if the user confirms it at a Step 1 prompt (full combined prompt or the - drift-clean close-candidate prompt). Declining either prompt leaves the item + freshness-clean close-candidate prompt). Declining either prompt leaves the item as a standing ⚠️ in the checklist, never a silent deletion. diff --git a/commands/primer.md b/commands/primer.md index 537d2c2..eed537a 100644 --- a/commands/primer.md +++ b/commands/primer.md @@ -40,13 +40,20 @@ migrations (`git mv` in Step 3c, `git rm` in Step 3d). name it lists, in the order given, then stop.** Do not re-derive which steps should run from the individual `KEY=value` facts printed above `STEPS=` — those are for transparency/debugging only, not a second -source of dispatch truth. If `STEPS` does not contain `refresh`, run Step 5 (check mode) as the -final step, after everything else `STEPS` named — this covers both the -fully-empty case (primer is current, nothing else to do) and a -migrations-only case (migrations ran, but the primer itself isn't -otherwise stale; Step 5's status report is still owed). If `STEPS` -contains `refresh`, Step 4 is the terminal step — its own reporting -already covers what Step 5 would say, so do not run Step 5 afterward. +source of dispatch truth. If `STEPS` contains `slim_migrate`, Step 4b +is terminal — do not run Step 4 or Step 5 afterward. Else if `STEPS` +contains `refresh`, Step 4 is terminal (its reporting covers what +Step 5 would say) — but first gate with `require_script` + +`primer-validate.sh` on the current primer; if validate fails with +fat-class reasons (headings outside the hard template, banlisted +`git log` content, line-budget blowouts, Mid-flight >5) **or** the +primer still has an `## Outstanding items` heading / leftover +`.session-continuity/BACKLOG.md` fossil, run Step 4b instead of +Step 4. Else run Step 5 (check mode) as the final step after +everything else `STEPS` named — this covers both the fully-empty case +(primer is current, nothing else to do) and a migrations-only case +(migrations ran, but the primer itself isn't otherwise stale; Step 5's +status report is still owed). | Name in `STEPS` | Run | |---|---| @@ -55,14 +62,16 @@ already covers what Step 5 would say, so do not run Step 5 afterward. | `outstanding_split` | Step 3b | | `backlog_rename` | Step 3c | | `backlog_to_issues` | Step 3d | +| `slim_migrate` | Step 4b | | `refresh` | Step 4 | Steps 3, 3b, 3c, and 3d's own bodies still say to "fall through" to refresh or check mode after they finish — that phrasing predates this dispatch. Treat it as already satisfied by the rule above: continue to -the next name in `STEPS` (if any), then apply the refresh/Step-5 rule -once, at the very end. Do not let a step's own fall-through sentence -trigger Step 4 or Step 5 a second time. +the next name in `STEPS` (if any), then apply the +slim-migrate/refresh/Step-5 rule once, at the very end. Do not let a +step's own fall-through sentence trigger Step 4, 4b, or Step 5 a +second time. ## Step 2 — Init mode @@ -82,7 +91,6 @@ trigger Step 4 or Step 5 a second time. [ -f package.json ] && grep -m1 '"name"' package.json [ -f Cargo.toml ] && grep -m1 '^name' Cargo.toml [ -f pyproject.toml ] && grep -m1 '^name' pyproject.toml - git log --oneline -5 [ -f package.json ] && grep -A1 '"scripts"' package.json | grep '"test"' find . -maxdepth 2 -not -path './node_modules/*' -not -path './.git/*' [ -f CLAUDE.md ] && echo "--- CLAUDE.md ---" && cat CLAUDE.md @@ -120,21 +128,32 @@ trigger Step 4 or Step 5 a second time. **If `DERIVE_STATUS` is nonzero, or `$DERIVE_OUTPUT` has no `PROJECT_NAME=` line:** report `$DERIVE_OUTPUT` to the user and ask for - `{{PROJECT_NAME}}`, the commit placeholders, and `{{TEST_COMMAND_SUMMARY}}` - manually in Step 7 below — never fabricate these from a failed script. + `{{PROJECT_NAME}}` and `{{TEST_COMMAND_SUMMARY}}` manually in Step 7 + below — never fabricate these from a failed script. **Otherwise**, fill directly from `$DERIVE_OUTPUT`'s fields: - - `{{PROJECT_NAME}}` — `PROJECT_NAME`. - - `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}` — `WORKING_DIRECTORY_ABSOLUTE_PATH`. - - `{{LATEST_COMMIT_HASH_N}}` / `{{LATEST_COMMIT_SUBJECT_N}}` — for each - `N` from 1 to `COMMIT_COUNT`, `LATEST_COMMIT_HASH_N` / - `LATEST_COMMIT_SUBJECT_N`. If `COMMIT_COUNT` is below 5, leave the - template's remaining `N` slots as `TBD` rather than writing empty pairs. - - `{{TEST_COMMAND_SUMMARY}}` — `TEST_COMMAND_SUMMARY`, verbatim. - - `{{REPO_LAYOUT_SUMMARY}}` — from the `find` output above, plus a one-line description Claude infers from the file extensions present. - - `{{MODULES_TABLE}}` — if the `@module` grep above found matches, build one table row per file: Component = file path, Purpose = the `@module` value (plus the docblock's one-line description if present), Notes = the adjacent `Exports:` line if present. If it found nothing, leave `TBD` as before — don't invent structure that isn't there. - - `{{WORKFLOW_CONVENTIONS}} (draft)` — if `CLAUDE.md` exists (cat output above), draft this field by quoting its relevant conventions (runtime choice, commit style, workflow/never-do rules) under a "Conventions inherited from CLAUDE.md" sub-heading, instead of leaving it blank for the user to retype. Present the draft in Step 7 for confirmation rather than asking cold. -7. Ask the user for the blanks that can't be derived: `{{GROUND_RULES}}`, `{{WHERE_TO_LOOK_ROWS}}`, `{{STUCK_ESCALATION_STEPS}}`, and `{{WORKFLOW_CONVENTIONS}}` only if no `CLAUDE.md` draft was produced above. If a draft was produced, show it and ask the user to confirm or amend it rather than asking a blank question. **Wait for their answer.** Do not proceed to Step 9 until the user responds. + - **SESSION_PRIMER.md (thin hard template):** `{{PROJECT_NAME}}` — + `PROJECT_NAME`. Leave `{{MID_FLIGHT_BULLET}}` for Step 7 (or set + one honest TBD bullet). Do **not** embed git-log blocks, test-count + tables, or Outstanding-items sections — the thin template has no + place for them. Peers stubs are already in the template. + - **PROJECT_CONTEXT.md (stable):** + - `{{WORKING_DIRECTORY_ABSOLUTE_PATH}}` — `WORKING_DIRECTORY_ABSOLUTE_PATH`. + - `{{TEST_COMMAND_SUMMARY}}` — `TEST_COMMAND_SUMMARY`, verbatim. + - `{{REPO_LAYOUT_SUMMARY}}` — from the `find` output above, plus a one-line description Claude infers from the file extensions present. + - `{{MODULES_TABLE}}` — if the `@module` grep above found matches, build one table row per file: Component = file path, Purpose = the `@module` value (plus the docblock's one-line description if present), Notes = the adjacent `Exports:` line if present. If it found nothing, leave `TBD` as before — don't invent structure that isn't there. + - `{{WORKFLOW_CONVENTIONS}} (draft)` — if `CLAUDE.md` exists (cat output above), draft this field by quoting its relevant conventions (runtime choice, commit style, workflow/never-do rules) under a "Conventions inherited from CLAUDE.md" sub-heading, instead of leaving it blank for the user to retype. Present the draft in Step 7 for confirmation rather than asking cold. + + After the thin primer is written, print the install-order blurb once: + > Install order: primer → graphify (commit `graphify-out/graph.json`) → engrim → `/session-continuity:doctor`. +7. Ask the user for the blanks that can't be derived: up to 5 Mid-flight + bullets for the primer (`{{MID_FLIGHT_BULLET}}` / additional `- ` + lines, capped at 5), plus `{{GROUND_RULES}}`, `{{WHERE_TO_LOOK_ROWS}}`, + `{{STUCK_ESCALATION_STEPS}}`, and `{{WORKFLOW_CONVENTIONS}}` only if no + `CLAUDE.md` draft was produced above. If a draft was produced, show it + and ask the user to confirm or amend it rather than asking a blank + question. **Wait for their answer.** Do not proceed to Step 9 until + the user responds. **Backlog.** Do not write a markdown backlog file. If origin contains `github.com` and the user named follow-ups, file each as a GitHub Issue: @@ -146,7 +165,7 @@ trigger Step 4 or Step 5 a second time. Title plus 1-3 sentences per issue. If they said "none" or skipped, file nothing. 8. **Replace any remaining `{{PLACEHOLDER}}` tokens with `TBD` before staging.** If the user skipped a field, declined to answer, or asked you to stage/commit without filling everything in, substitute `TBD` (with an empty body line where the template had prose). Never leave `{{...}}` syntax in a file you are about to stage — `grep -n '{{' .session-continuity/SESSION_PRIMER.md .session-continuity/PROJECT_CONTEXT.md .session-continuity/LEARNINGS.md .session-continuity/ROADMAP.md` must return nothing after this step. 9. Stage four files: `git add .session-continuity/SESSION_PRIMER.md .session-continuity/PROJECT_CONTEXT.md .session-continuity/LEARNINGS.md .session-continuity/ROADMAP.md`. -10. Tell the user: "Primer, PROJECT_CONTEXT, ROADMAP, and LEARNINGS staged. Review and commit with `git commit -m 'docs: initialize session continuity'` when ready." Include a one-line note listing any fields that were set to `TBD` so the user knows what to fill in later. If issues were filed, list their `#N` numbers. +10. Tell the user: "Primer, PROJECT_CONTEXT, ROADMAP, and LEARNINGS staged. Review and commit with `git commit -m 'docs: initialize session continuity'` when ready." Include a one-line note listing any fields that were set to `TBD` so the user knows what to fill in later. If issues were filed, list their `#N` numbers. Remind them: `/session-continuity:doctor` stays red until peers exist — finish install order (graphify commit of `graphify-out/graph.json`, then engrim on PATH) and re-doctor. **Do not commit automatically.** The user commits when ready. @@ -289,124 +308,124 @@ the file unless the issues exist. ## Step 4 — Refresh mode +Thin refresh only. Rewrite **Mid-flight** and **Confirm** (and update +**Peers** status lines in the file). Peers status lines are +agent-maintained on refresh/slim-migrate only — **not** by SessionStart. +Do **not** regenerate git-log blocks, test-count tables, or any other +fat-primer section. + 1. Read the current `.session-continuity/SESSION_PRIMER.md`. -2. Regenerate the `git log --oneline -5` block. **One Bash call**, timed: +2. Optionally surface activity since the last primer refresh (for the + backlog prompt below — not for writing into the primer). **One Bash + call**, timed: ```bash _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") - git log --oneline -5 + LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) + git log "$LAST_PRIMER_COMMIT"..HEAD --oneline _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") - bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-git-log-refresh --duration="$_PERF_DURATION" + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-activity-surface --duration="$_PERF_DURATION" ``` - Use the output above to regenerate the primer's block. -3. Run the shared test-count rerun script, timed: + Run `bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" .` for + the current open-issue list. Present the subject list from the + `git log` output above as candidate prompts (candidate list, not + auto-close — wait for the user's answer). +3. Ask the user: "Backlog — anything to close (finished) or file (new follow-ups)?" Close with `gh issue close N --reason completed` only after checking the claim against the actual code. File new follow-ups with `gh issue create --label backlog --title "..." --body "..."` (title plus 1-3 sentences). Never create or edit `.session-continuity/BACKLOG.md`. +4. Rewrite Mid-flight (≤5 bullets of currently open work + pointer + optional one-line trap) and Confirm (≤5 counted commands that falsify Mid-flight if they fail). Update Peers status lines from a `require_script` + `peer-probes.sh` probe if useful — do not grow the file past the hard template. +5. After the write, validate before staging: ```bash - _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") - LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" - if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" 1; then - RERUN_OUTPUT="$(bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/test-count-rerun.sh" . "$LAST_PRIMER_COMMIT" 2>&1)" - RERUN_STATUS=$? + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" .session-continuity/SESSION_PRIMER.md else - RERUN_OUTPUT="$SC_REQUIRE_SCRIPT_MSG" - RERUN_STATUS=1 + echo "$SC_REQUIRE_SCRIPT_MSG" >&2 + false fi - _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") - _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") - RETRIES=$(printf '%s' "$RERUN_OUTPUT" | awk -F= '/^RETRIES=/{print $2}') - bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-test-count-rerun --duration="$_PERF_DURATION" --retries="${RETRIES:-0}" - echo "$RERUN_OUTPUT" - echo "RERUN_STATUS=$RERUN_STATUS" ``` - **If `RERUN_STATUS` is nonzero, or `$RERUN_OUTPUT` has no `MODE=` line:** - report `$RERUN_OUTPUT` to the user and fall back to `TBD` for this - axis — never fabricate a drift verdict from a failed script. - - **Otherwise**, report per `MODE`: - - `skip` — no relevant file changed; say nothing (matches today's - silent skip). - - `no-command` — no test command recorded; nothing to check. - - `no-count`, `RETRIES=0`, `DRIFT=0` always — nothing recorded yet - to compare against; no report needed on this axis. - - `run` with `DRIFT=0` — the count held (whether on the first try or - after majority-vote confirmation); no report needed. - - `run` with `DRIFT=1` — report drift using `PINNED_COUNT` - (`"Test count drifted: recorded <RECORDED_COUNT>, now - <PINNED_COUNT> (confirmed over <RETRIES>+1 runs)."`). - - `run` with `SPREAD=1` — report instability using the comma-joined - `OBSERVED` values (`"Test suite is unstable: saw - <OBSERVED, /-joined> across 3 runs."`), not a drift verdict. - - `run` with `UNPARSEABLE=1` and no `PINNED_COUNT` — report - `"Test command produced no parseable count after <RETRIES>+1 - attempts."` -4. **Surface activity since the last primer refresh.** **One Bash - call**, timed: + **On failure: stop.** Show the validator's stderr (`INVALID: …` lines) + to the user. Do not stage a failing primer. If the failure is fat-class + or fossils remain, divert to Step 4b instead of retrying a partial + patch. +6. Stage the updated primer: `git add .session-continuity/SESSION_PRIMER.md`. +7. Tell the user: "Primer refreshed and staged. Include it in your next commit (same commit as the substantive change — do not primer-commit alone)." + +## Step 4b — Slim-migrate mode + +One-shot rewrite from a fat (or fossil-bearing) primer to the thin hard +template. Triggered when `STEPS` contains `slim_migrate`, or when Step 4's +pre-gate / post-write validate fails with fat-class reasons, or leftover +`## Outstanding items` / `.session-continuity/BACKLOG.md` fossils remain. + +1. Read the current fat primer (and any Outstanding / BACKLOG fossils) in full. +2. Copy the thin template from `${CLAUDE_PLUGIN_ROOT}/skills/session-continuity/templates/SESSION_PRIMER.md` over `.session-continuity/SESSION_PRIMER.md`. +3. Fill `{{PROJECT_NAME}}` from the old primer title or repo name. +4. Select ≤5 Mid-flight bullets from the old narrative (open work + pointer + optional trap). Remaining open work → file as GitHub Issues labeled `backlog` if needed; drop the rest. Do not dual-write old sections. +5. Write Confirm commands (≤5 counted) that falsify those Mid-flight bullets if they fail. Update Peers status lines (agent-maintained here — not SessionStart). +6. Validate before stage: ```bash - _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") - LAST_PRIMER_COMMIT=$(git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md) - git log "$LAST_PRIMER_COMMIT"..HEAD --oneline - _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") - _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") - bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-4-activity-surface --duration="$_PERF_DURATION" + source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" .session-continuity/SESSION_PRIMER.md + else + echo "$SC_REQUIRE_SCRIPT_MSG" >&2 + false + fi ``` - Run `bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/backlog-issues.sh" .` for - the current open-issue list. Present the subject list from the - `git log` output above to the - user as candidate prompts: - > "Since the last primer refresh, these commits landed: - > - `<sha> <subject>` - > - … - > - > Any of these resolve open backlog issues, or warrant a new LEARNINGS entry?" - This is a candidate list, not an auto-close. Do not close issues based on subject heuristics — wait for the user's answer. -5. Ask the user: "Backlog — anything to close (finished) or file (new follow-ups)?" -6. Close with `gh issue close N --reason completed` only after checking - the claim against the actual code — one grep or read per load-bearing - claim, even if the user confirms it from memory or a commit subject - matched the issue title. A subject-line match does not mean the - change shipped, and a fix landing inside an unrelated commit can - leave an issue open when it already shipped — check both directions. - File new follow-ups with `gh issue create --label backlog --title - "..." --body "..."` (title plus 1-3 sentences). Never create or edit - `.session-continuity/BACKLOG.md`. -7. Stage the updated primer: `git add .session-continuity/SESSION_PRIMER.md`. -8. Tell the user: "Primer refreshed and staged. Include it in your next commit (same commit as the substantive change — do not primer-commit alone)." + **On failure: stop** and show stderr. Do not stage. +7. If a markdown BACKLOG fossil exists and origin is GitHub, prefer migrating items to Issues (same rules as Step 3d) rather than leaving the fossil; otherwise leave it and note that doctor will warn. +8. Stage: `git add .session-continuity/SESSION_PRIMER.md` (and any Issue-migration paths touched). +9. Tell the user the primer was slim-migrated to the thin hard template, list Mid-flight bullets chosen, and remind install order if peers are still missing: primer → graphify (commit `graphify-out/graph.json`) → engrim → re-doctor. + +**Do not commit automatically.** Staging only. ## Step 5 — Check mode -Gather the report data in **one Bash call**, timed, via the shared status -script (also used by `hooks/session-start.sh`, so the two can no longer -disagree about sha/mtime/counts): +Gather status, shape, and peer summary — all via `require_script`. Timed: ```bash _PERF_START=$(date +%s.%N 2>/dev/null || echo "$SECONDS") source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/require-script.sh" + if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-status.sh" 1; then bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-status.sh" . else echo "⚠️ $SC_REQUIRE_SCRIPT_MSG" fi + +echo "--- primer validate ---" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" .session-continuity/SESSION_PRIMER.md \ + && echo "PRIMER_VALIDATE=ok" || echo "PRIMER_VALIDATE=fail" +else + echo "⚠️ $SC_REQUIRE_SCRIPT_MSG" + echo "PRIMER_VALIDATE=fail" +fi + +echo "--- peer probes ---" +if require_script "${CLAUDE_PLUGIN_ROOT}/hooks/lib/peer-probes.sh" 1; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/peer-probes.sh" . +else + echo "⚠️ $SC_REQUIRE_SCRIPT_MSG" + echo "ENGRIM=?" + echo "GRAPHIFY=?" +fi + _PERF_END=$(date +%s.%N 2>/dev/null || echo "$SECONDS") _PERF_DURATION=$(awk -v a="$_PERF_START" -v b="$_PERF_END" 'BEGIN{printf "%.3f", b-a}' 2>/dev/null || echo "$(( _PERF_END - _PERF_START ))") bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/perf-log.sh" record --source=command --name=primer --step=step-5-check-mode --duration="$_PERF_DURATION" ``` -The output above is four `KEY=value` lines: `HEAD_SHA=`, `PRIMER_MTIME=`, -`BACKLOG_COUNT=`, `LEARNINGS_COUNT=` (any of them may read `?` if that -probe failed — report it as `?`, never invent a value). Report: - -``` -.session-continuity/SESSION_PRIMER.md: up to date against HEAD (<HEAD_SHA>) -Last refresh: <PRIMER_MTIME> -Backlog: <BACKLOG_COUNT> -Learnings: <LEARNINGS_COUNT> -``` +Report `primer-status.sh`'s `KEY=value` lines (any `?` stays `?` — never +invent), then shape (`PRIMER_VALIDATE=ok|fail` plus any `INVALID:` +reasons), then peers (`ENGRIM=…`, `GRAPHIFY=…`). If peers are not ok, +include install order: primer → graphify (commit `graphify-out/graph.json`) +→ engrim → re-doctor. No changes made. Exit. diff --git a/graphify-out/graph.json b/graphify-out/graph.json new file mode 100644 index 0000000..710995b --- /dev/null +++ b/graphify-out/graph.json @@ -0,0 +1,28498 @@ +{ + "directed": false, + "multigraph": false, + "graph": {}, + "nodes": [ + { + "id": "contributing", + "label": "CONTRIBUTING.md", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "page", + "norm_label": "contributing.md", + "source_file": "CONTRIBUTING.md", + "source_location": "L1" + }, + { + "id": "privacy", + "label": "PRIVACY.md", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "page", + "norm_label": "privacy.md", + "source_file": "PRIVACY.md", + "source_location": "L1" + }, + { + "id": "privacy_changes_to_this_policy", + "label": "Changes to this policy", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changes to this policy", + "source_file": "PRIVACY.md", + "source_location": "L66" + }, + { + "id": "privacy_contact", + "label": "Contact", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "contact", + "source_file": "PRIVACY.md", + "source_location": "L70" + }, + { + "id": "privacy_data_retention", + "label": "Data retention", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "data retention", + "source_file": "PRIVACY.md", + "source_location": "L62" + }, + { + "id": "privacy_external_network_calls", + "label": "External network calls", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "external network calls", + "source_file": "PRIVACY.md", + "source_location": "L20" + }, + { + "id": "privacy_privacy_policy", + "label": "Privacy policy", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "privacy policy", + "source_file": "PRIVACY.md", + "source_location": "L1" + }, + { + "id": "privacy_short_version", + "label": "Short version", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "short version", + "source_file": "PRIVACY.md", + "source_location": "L7" + }, + { + "id": "privacy_third_party_services", + "label": "Third-party services", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "third-party services", + "source_file": "PRIVACY.md", + "source_location": "L58" + }, + { + "id": "privacy_what_data_the_plugin_handles", + "label": "What data the plugin handles", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what data the plugin handles", + "source_file": "PRIVACY.md", + "source_location": "L11" + }, + { + "id": "privacy_what_the_plugin_does_not_do", + "label": "What the plugin does **not** do", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what the plugin does **not** do", + "source_file": "PRIVACY.md", + "source_location": "L50" + }, + { + "id": "readme", + "label": "README.md", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "page", + "norm_label": "readme.md", + "source_file": "README.md", + "source_location": "L1" + }, + { + "id": "readme_contributing", + "label": "Contributing", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "contributing", + "source_file": "README.md", + "source_location": "L251" + }, + { + "id": "readme_install", + "label": "Install", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "install", + "source_file": "README.md", + "source_location": "L38" + }, + { + "id": "readme_license", + "label": "License", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "license", + "source_file": "README.md", + "source_location": "L259" + }, + { + "id": "readme_platform_notes", + "label": "Platform notes", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "platform notes", + "source_file": "README.md", + "source_location": "L236" + }, + { + "id": "readme_privacy", + "label": "Privacy", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "privacy", + "source_file": "README.md", + "source_location": "L255" + }, + { + "id": "readme_session_continuity", + "label": "session-continuity", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session-continuity", + "source_file": "README.md", + "source_location": "L1" + }, + { + "id": "readme_session_continuity_backlog", + "label": "`/session-continuity:backlog`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:backlog`", + "source_file": "README.md", + "source_location": "L101" + }, + { + "id": "readme_session_continuity_doctor", + "label": "`/session-continuity:doctor`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:doctor`", + "source_file": "README.md", + "source_location": "L93" + }, + { + "id": "readme_session_continuity_end_session", + "label": "`/session-continuity:end-session`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:end-session`", + "source_file": "README.md", + "source_location": "L83" + }, + { + "id": "readme_session_continuity_help", + "label": "`/session-continuity:help`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:help`", + "source_file": "README.md", + "source_location": "L113" + }, + { + "id": "readme_session_continuity_learning", + "label": "`/session-continuity:learning`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:learning`", + "source_file": "README.md", + "source_location": "L79" + }, + { + "id": "readme_session_continuity_learnings", + "label": "`/session-continuity:learnings`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:learnings`", + "source_file": "README.md", + "source_location": "L105" + }, + { + "id": "readme_session_continuity_primer", + "label": "`/session-continuity:primer`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:primer`", + "source_file": "README.md", + "source_location": "L67" + }, + { + "id": "readme_session_continuity_spike_check", + "label": "`/session-continuity:spike-check`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:spike-check`", + "source_file": "README.md", + "source_location": "L97" + }, + { + "id": "readme_session_continuity_update", + "label": "`/session-continuity:update`", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:update`", + "source_file": "README.md", + "source_location": "L109" + }, + { + "id": "readme_team_wide_use", + "label": "Team-wide use", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "team-wide use", + "source_file": "README.md", + "source_location": "L228" + }, + { + "id": "readme_the_commands", + "label": "The commands", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the commands", + "source_file": "README.md", + "source_location": "L65" + }, + { + "id": "readme_the_four_files_plus_the_queue", + "label": "The four files, plus the queue", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the four files, plus the queue", + "source_file": "README.md", + "source_location": "L49" + }, + { + "id": "readme_the_hooks", + "label": "The hooks", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the hooks", + "source_file": "README.md", + "source_location": "L117" + }, + { + "id": "readme_updating", + "label": "Updating", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "updating", + "source_file": "README.md", + "source_location": "L240" + }, + { + "id": "readme_usage", + "label": "Usage", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "usage", + "source_file": "README.md", + "source_location": "L145" + }, + { + "id": "readme_what_goes_where", + "label": "What goes where", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what goes where", + "source_file": "README.md", + "source_location": "L185" + }, + { + "id": "readme_what_it_is_not", + "label": "What it is not", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what it is not", + "source_file": "README.md", + "source_location": "L216" + }, + { + "id": "readme_what_s_in_the_box", + "label": "What's in the box", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what's in the box", + "source_file": "README.md", + "source_location": "L15" + }, + { + "id": "readme_why_four_files_plus_github_issues", + "label": "Why four files plus GitHub Issues", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "why four files plus github issues", + "source_file": "README.md", + "source_location": "L200" + }, + { + "id": "readme_why_this_exists", + "label": "Why this exists", + "_origin": "ast", + "community": 0, + "community_name": "session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "why this exists", + "source_file": "README.md", + "source_location": "L5" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3", + "label": "2026-04-28-end-session-command-v0.3.md", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-04-28-end-session-command-v0.3.md", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_execution_handoff", + "label": "Execution handoff", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "execution handoff", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L813" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L17" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_self_review", + "label": "Self-review", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L767" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "label": "`/session-continuity:end-session` v0.3 Implementation Plan", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:end-session` v0.3 implementation plan", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_10_wrap_up", + "label": "Task 10: Wrap up", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 10: wrap up", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L745" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_1_precondition_check_clean_starting_state", + "label": "Task 1: Precondition check \u2014 clean starting state", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: precondition check \u2014 clean starting state", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L36" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_2_write_commands_end_session_md", + "label": "Task 2: Write `commands/end-session.md`", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: write `commands/end-session.md`", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L64" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_3_bump_plugin_json_to_0_3_0", + "label": "Task 3: Bump `plugin.json` to 0.3.0", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: bump `plugin.json` to 0.3.0", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L272" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_4_update_changelog_md", + "label": "Task 4: Update `CHANGELOG.md`", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: update `changelog.md`", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L311" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_5_update_readme_md", + "label": "Task 5: Update `README.md`", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: update `readme.md`", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L364" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_6_update_skill_md", + "label": "Task 6: Update `SKILL.md`", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: update `skill.md`", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L419" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_7_live_smoke_test_in_a_scratch_repo", + "label": "Task 7: Live smoke test in a scratch repo", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: live smoke test in a scratch repo", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L462" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_8_tag_and_publish_v0_3_0", + "label": "Task 8: Tag and publish v0.3.0", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: tag and publish v0.3.0", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L606" + }, + { + "id": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_9_dogfood_run_session_continuity_end_session_on_this_repo", + "label": "Task 9: Dogfood \u2014 run `/session-continuity:end-session` on this repo", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 9: dogfood \u2014 run `/session-continuity:end-session` on this repo", + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L692" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design", + "label": "2026-04-28-end-session-command-design.md", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-04-28-end-session-command-design.md", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_acceptance_criteria", + "label": "Acceptance criteria", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "acceptance criteria", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L184" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_architecture", + "label": "Architecture", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "architecture", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L124" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_behavior", + "label": "Behavior", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "behavior", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L35" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_command_surface", + "label": "Command surface", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "command surface", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L28" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_goal", + "label": "Goal", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goal", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L16" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_layer_1_prose_consistency_check", + "label": "Layer 1 \u2014 Prose consistency check", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "layer 1 \u2014 prose consistency check", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L157" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_layer_2_live_smoke_test_in_a_scratch_repo", + "label": "Layer 2 \u2014 Live smoke test in a scratch repo", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "layer 2 \u2014 live smoke test in a scratch repo", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L167" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_layer_3_dogfood_in_the_session_continuity_repo_itself", + "label": "Layer 3 \u2014 Dogfood in the session-continuity repo itself", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "layer 3 \u2014 dogfood in the session-continuity repo itself", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L180" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_no_new_hooks_no_new_templates", + "label": "No new hooks, no new templates", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "no new hooks, no new templates", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L139" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_non_behaviors_explicit", + "label": "Non-behaviors (explicit)", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-behaviors (explicit)", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L118" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L20" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_open_questions_not_blocking", + "label": "Open questions (not blocking)", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "open questions (not blocking)", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L194" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_out_of_scope_decided_during_brainstorm", + "label": "Out-of-scope (decided during brainstorm)", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out-of-scope (decided during brainstorm)", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L202" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_precondition", + "label": "Precondition", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "precondition", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L37" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L7" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "label": "`/session-continuity:end-session` \u2014 Design Spec", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:end-session` \u2014 design spec", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_single_file_command_subroutine_by_reference", + "label": "Single-file command, subroutine-by-reference", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "single-file command, subroutine-by-reference", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L126" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_step_1_refresh_the_primer", + "label": "Step 1 \u2014 Refresh the primer", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 \u2014 refresh the primer", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L45" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_step_2_session_reflection_for_learnings", + "label": "Step 2 \u2014 Session reflection for learnings", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 \u2014 session reflection for learnings", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L59" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_step_3_final_checklist", + "label": "Step 3 \u2014 Final checklist", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3 \u2014 final checklist", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L82" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_testing_strategy", + "label": "Testing strategy", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing strategy", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L153" + }, + { + "id": "meta_superpowers_specs_2026_04_28_end_session_command_design_versioning_release", + "label": "Versioning & release", + "_origin": "ast", + "community": 1, + "community_name": "`/session-continuity:end-session` v0.3 Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "versioning & release", + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L146" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521", + "label": "improvements_20260521.md", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "page", + "norm_label": "improvements_20260521.md", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_10_quick_wins_ranked", + "label": "10. Quick wins ranked", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "10. quick wins ranked", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L112" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_1_drift_detection_what_works_what_misses", + "label": "1. Drift detection \u2014 what works, what misses", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "1. drift detection \u2014 what works, what misses", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L3" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_2_primer_only_commit_rule_needs_branch_aware_nuance", + "label": "2. Primer-only-commit rule needs branch-aware nuance", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "2. primer-only-commit rule needs branch-aware nuance", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L14" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_3_init_mode_could_derive_much_more", + "label": "3. Init mode could derive much more", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "3. init mode could derive much more", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L25" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_4_learnings_entry_creation_and_search", + "label": "4. LEARNINGS \u2014 entry creation and search", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "4. learnings \u2014 entry creation and search", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L36" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_5_end_session_skill_never_fired_during_a_6_hour_session", + "label": "5. End-session skill never fired during a 6-hour session", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "5. end-session skill never fired during a 6-hour session", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L56" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_6_the_primer_file_is_now_320_lines_context_cost", + "label": "6. The primer file is now ~320 lines \u2014 context cost", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "6. the primer file is now ~320 lines \u2014 context cost", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L67" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_7_schema_validation_for_primer_fields", + "label": "7. Schema validation for primer fields", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "7. schema validation for primer fields", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L80" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_8_plugin_awareness_of_sibling_tools", + "label": "8. Plugin awareness of sibling tools", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "8. plugin awareness of sibling tools", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L88" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_9_specific_friction_moments_worth_recording", + "label": "9. Specific friction moments worth recording", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "9. specific friction moments worth recording", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L96" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_closed_outstanding_items_pile_up", + "label": "Closed outstanding items pile up", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "closed outstanding items pile up", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L77" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_cross_references_decay", + "label": "Cross-references decay", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "cross-references decay", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L47" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_last_reviewed_dating_is_manual_always_stale", + "label": "\"Last reviewed\" dating is manual + always stale", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "\"last reviewed\" dating is manual + always stale", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L53" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_mix_of_stable_and_volatile_content", + "label": "Mix of stable and volatile content", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "mix of stable and volatile content", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L71" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_numbering_should_be_automatic", + "label": "Numbering should be automatic", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "numbering should be automatic", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L38" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_search_by_symptom_is_hard", + "label": "Search-by-symptom is hard", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "search-by-symptom is hard", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L50" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "label": "session-continuity plugin \u2014 usage feedback + recommendations", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session-continuity plugin \u2014 usage feedback + recommendations", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_what_misses", + "label": "What misses", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what misses", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L9" + }, + { + "id": "meta_superpowers_recommendations_improvements_20260521_what_works", + "label": "What works", + "_origin": "ast", + "community": 10, + "community_name": "session-continuity plugin \u2014 usage feedback + recommendations", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what works", + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L5" + }, + { + "id": "changelog_0_10_0_2026_06_17", + "label": "[0.10.0] \u2014 2026-06-17", + "_origin": "ast", + "community": 100, + "community_name": "[0.10.0] \u2014 2026-06-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.10.0] \u2014 2026-06-17", + "source_file": "CHANGELOG.md", + "source_location": "L592" + }, + { + "id": "changelog_added_594", + "label": "Added", + "_origin": "ast", + "community": 100, + "community_name": "[0.10.0] \u2014 2026-06-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L594" + }, + { + "id": "changelog_compatibility_599", + "label": "Compatibility", + "_origin": "ast", + "community": 100, + "community_name": "[0.10.0] \u2014 2026-06-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L599" + }, + { + "id": "changelog_0_11_0_2026_07_01", + "label": "[0.11.0] \u2014 2026-07-01", + "_origin": "ast", + "community": 101, + "community_name": "[0.11.0] \u2014 2026-07-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.11.0] \u2014 2026-07-01", + "source_file": "CHANGELOG.md", + "source_location": "L582" + }, + { + "id": "changelog_added_584", + "label": "Added", + "_origin": "ast", + "community": 101, + "community_name": "[0.11.0] \u2014 2026-07-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L584" + }, + { + "id": "changelog_compatibility_589", + "label": "Compatibility", + "_origin": "ast", + "community": 101, + "community_name": "[0.11.0] \u2014 2026-07-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L589" + }, + { + "id": "changelog_0_12_2_2026_08_12", + "label": "[0.12.2] \u2014 2026-08-12", + "_origin": "ast", + "community": 102, + "community_name": "[0.12.2] \u2014 2026-08-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.12.2] \u2014 2026-08-12", + "source_file": "CHANGELOG.md", + "source_location": "L526" + }, + { + "id": "changelog_added_542", + "label": "Added", + "_origin": "ast", + "community": 102, + "community_name": "[0.12.2] \u2014 2026-08-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L542" + }, + { + "id": "changelog_fixed_528", + "label": "Fixed", + "_origin": "ast", + "community": 102, + "community_name": "[0.12.2] \u2014 2026-08-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L528" + }, + { + "id": "changelog_0_12_3_2026_08_12", + "label": "[0.12.3] \u2014 2026-08-12", + "_origin": "ast", + "community": 103, + "community_name": "[0.12.3] \u2014 2026-08-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.12.3] \u2014 2026-08-12", + "source_file": "CHANGELOG.md", + "source_location": "L507" + }, + { + "id": "changelog_added_509", + "label": "Added", + "_origin": "ast", + "community": 103, + "community_name": "[0.12.3] \u2014 2026-08-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L509" + }, + { + "id": "changelog_fixed_517", + "label": "Fixed", + "_origin": "ast", + "community": 103, + "community_name": "[0.12.3] \u2014 2026-08-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L517" + }, + { + "id": "changelog_0_14_0_2026_08_13", + "label": "[0.14.0] \u2014 2026-08-13", + "_origin": "ast", + "community": 104, + "community_name": "[0.14.0] \u2014 2026-08-13", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.14.0] \u2014 2026-08-13", + "source_file": "CHANGELOG.md", + "source_location": "L457" + }, + { + "id": "changelog_fixed_472", + "label": "Fixed", + "_origin": "ast", + "community": 104, + "community_name": "[0.14.0] \u2014 2026-08-13", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L472" + }, + { + "id": "changelog_removed_459", + "label": "Removed", + "_origin": "ast", + "community": 104, + "community_name": "[0.14.0] \u2014 2026-08-13", + "file_type": "document", + "node_kind": "heading", + "norm_label": "removed", + "source_file": "CHANGELOG.md", + "source_location": "L459" + }, + { + "id": "changelog_0_16_0_2026_08_22", + "label": "[0.16.0] \u2014 2026-08-22", + "_origin": "ast", + "community": 105, + "community_name": "[0.16.0] \u2014 2026-08-22", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.16.0] \u2014 2026-08-22", + "source_file": "CHANGELOG.md", + "source_location": "L296" + }, + { + "id": "changelog_added_298", + "label": "Added", + "_origin": "ast", + "community": 105, + "community_name": "[0.16.0] \u2014 2026-08-22", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L298" + }, + { + "id": "changelog_considered_and_dropped", + "label": "Considered and dropped", + "_origin": "ast", + "community": 105, + "community_name": "[0.16.0] \u2014 2026-08-22", + "file_type": "document", + "node_kind": "heading", + "norm_label": "considered and dropped", + "source_file": "CHANGELOG.md", + "source_location": "L308" + }, + { + "id": "changelog_0_21_0_2026_08_31", + "label": "[0.21.0] \u2014 2026-08-31", + "_origin": "ast", + "community": 106, + "community_name": "[0.21.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.21.0] \u2014 2026-08-31", + "source_file": "CHANGELOG.md", + "source_location": "L158" + }, + { + "id": "changelog_added_160", + "label": "Added", + "_origin": "ast", + "community": 106, + "community_name": "[0.21.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L160" + }, + { + "id": "changelog_fixed_163", + "label": "Fixed", + "_origin": "ast", + "community": 106, + "community_name": "[0.21.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L163" + }, + { + "id": "changelog_0_22_0_2026_08_31", + "label": "[0.22.0] \u2014 2026-08-31", + "_origin": "ast", + "community": 107, + "community_name": "[0.22.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.22.0] \u2014 2026-08-31", + "source_file": "CHANGELOG.md", + "source_location": "L144" + }, + { + "id": "changelog_added_146", + "label": "Added", + "_origin": "ast", + "community": 107, + "community_name": "[0.22.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L146" + }, + { + "id": "changelog_changed_150", + "label": "Changed", + "_origin": "ast", + "community": 107, + "community_name": "[0.22.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L150" + }, + { + "id": "changelog_0_23_0_2026_09_01", + "label": "[0.23.0] \u2014 2026-09-01", + "_origin": "ast", + "community": 108, + "community_name": "[0.23.0] \u2014 2026-09-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.23.0] \u2014 2026-09-01", + "source_file": "CHANGELOG.md", + "source_location": "L131" + }, + { + "id": "changelog_added_133", + "label": "Added", + "_origin": "ast", + "community": 108, + "community_name": "[0.23.0] \u2014 2026-09-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L133" + }, + { + "id": "changelog_changed_139", + "label": "Changed", + "_origin": "ast", + "community": 108, + "community_name": "[0.23.0] \u2014 2026-09-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L139" + }, + { + "id": "changelog_0_25_0_2026_09_01", + "label": "[0.25.0] \u2014 2026-09-01", + "_origin": "ast", + "community": 109, + "community_name": "[0.25.0] \u2014 2026-09-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.25.0] \u2014 2026-09-01", + "source_file": "CHANGELOG.md", + "source_location": "L111" + }, + { + "id": "changelog_changed_122", + "label": "Changed", + "_origin": "ast", + "community": 109, + "community_name": "[0.25.0] \u2014 2026-09-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L122" + }, + { + "id": "changelog_fixed_113", + "label": "Fixed", + "_origin": "ast", + "community": 109, + "community_name": "[0.25.0] \u2014 2026-09-01", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L113" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design", + "label": "2026-09-07-github-issues-backlog-design.md", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-07-github-issues-backlog-design.md", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_call_sites", + "label": "Call sites", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "call sites", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L123" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_decisions", + "label": "Decisions", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "decisions", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L49" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "label": "Design: GitHub Issues replace BACKLOG.md", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design: github issues replace backlog.md", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_docs_version", + "label": "Docs / version", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "docs / version", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L250" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_doctor", + "label": "Doctor", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "doctor", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L171" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_goals", + "label": "Goals", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goals", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L22" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_hooks_lib_backlog_issues_sh", + "label": "`hooks/lib/backlog-issues.sh`", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/lib/backlog-issues.sh`", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L78" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L39" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L258" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_doctor_commands", + "label": "Primer, doctor, commands", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "primer, doctor, commands", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L148" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_init", + "label": "Primer init", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "primer init", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L150" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_migrate", + "label": "Primer migrate", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "primer migrate", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L156" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_privacy", + "label": "Privacy", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "privacy", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L187" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L6" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_runtime", + "label": "Runtime", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "runtime", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L74" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_session_continuity_backlog_and_end_session", + "label": "`/session-continuity:backlog` and `/end-session`", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:backlog` and `/end-session`", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L178" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_tests", + "label": "Tests", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "tests", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L227" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_this_repo_s_cut", + "label": "This repo's cut", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "this repo's cut", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L200" + }, + { + "id": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_write_path_skill_commands_not_a_daemon", + "label": "Write path (skill + commands, not a daemon)", + "_origin": "ast", + "community": 11, + "community_name": "Design: GitHub Issues replace BACKLOG.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "write path (skill + commands, not a daemon)", + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L131" + }, + { + "id": "changelog_0_35_0_2026_09_09", + "label": "[0.35.0] \u2014 2026-09-09", + "_origin": "ast", + "community": 110, + "community_name": "[0.35.0] \u2014 2026-09-09", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.35.0] \u2014 2026-09-09", + "source_file": "CHANGELOG.md", + "source_location": "L5" + }, + { + "id": "changelog_added", + "label": "Added", + "_origin": "ast", + "community": 110, + "community_name": "[0.35.0] \u2014 2026-09-09", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L7" + }, + { + "id": "changelog_fixed", + "label": "Fixed", + "_origin": "ast", + "community": 110, + "community_name": "[0.35.0] \u2014 2026-09-09", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L16" + }, + { + "id": "changelog_0_3_0_2026_04_28", + "label": "[0.3.0] \u2014 2026-04-28", + "_origin": "ast", + "community": 111, + "community_name": "[0.3.0] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.3.0] \u2014 2026-04-28", + "source_file": "CHANGELOG.md", + "source_location": "L710" + }, + { + "id": "changelog_added_712", + "label": "Added", + "_origin": "ast", + "community": 111, + "community_name": "[0.3.0] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L712" + }, + { + "id": "changelog_changed_715", + "label": "Changed", + "_origin": "ast", + "community": 111, + "community_name": "[0.3.0] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L715" + }, + { + "id": "changelog_0_4_1_2026_04_28", + "label": "[0.4.1] \u2014 2026-04-28", + "_origin": "ast", + "community": 112, + "community_name": "[0.4.1] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.4.1] \u2014 2026-04-28", + "source_file": "CHANGELOG.md", + "source_location": "L680" + }, + { + "id": "changelog_changed_686", + "label": "Changed", + "_origin": "ast", + "community": 112, + "community_name": "[0.4.1] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L686" + }, + { + "id": "changelog_fixed_682", + "label": "Fixed", + "_origin": "ast", + "community": 112, + "community_name": "[0.4.1] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L682" + }, + { + "id": "changelog_0_5_0_2026_05_12", + "label": "[0.5.0] \u2014 2026-05-12", + "_origin": "ast", + "community": 113, + "community_name": "[0.5.0] \u2014 2026-05-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.5.0] \u2014 2026-05-12", + "source_file": "CHANGELOG.md", + "source_location": "L668" + }, + { + "id": "changelog_changed_670", + "label": "Changed", + "_origin": "ast", + "community": 113, + "community_name": "[0.5.0] \u2014 2026-05-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L670" + }, + { + "id": "changelog_compatibility_677", + "label": "Compatibility", + "_origin": "ast", + "community": 113, + "community_name": "[0.5.0] \u2014 2026-05-12", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L677" + }, + { + "id": "changelog_0_5_1_2026_05_21", + "label": "[0.5.1] \u2014 2026-05-21", + "_origin": "ast", + "community": 114, + "community_name": "[0.5.1] \u2014 2026-05-21", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.5.1] \u2014 2026-05-21", + "source_file": "CHANGELOG.md", + "source_location": "L652" + }, + { + "id": "changelog_changed_654", + "label": "Changed", + "_origin": "ast", + "community": 114, + "community_name": "[0.5.1] \u2014 2026-05-21", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L654" + }, + { + "id": "changelog_compatibility_665", + "label": "Compatibility", + "_origin": "ast", + "community": 114, + "community_name": "[0.5.1] \u2014 2026-05-21", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L665" + }, + { + "id": "changelog_0_8_0_2026_06_15", + "label": "[0.8.0] \u2014 2026-06-15", + "_origin": "ast", + "community": 115, + "community_name": "[0.8.0] \u2014 2026-06-15", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.8.0] \u2014 2026-06-15", + "source_file": "CHANGELOG.md", + "source_location": "L610" + }, + { + "id": "changelog_added_612", + "label": "Added", + "_origin": "ast", + "community": 115, + "community_name": "[0.8.0] \u2014 2026-06-15", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L612" + }, + { + "id": "changelog_compatibility_618", + "label": "Compatibility", + "_origin": "ast", + "community": 115, + "community_name": "[0.8.0] \u2014 2026-06-15", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L618" + }, + { + "id": "changelog_0_9_0_2026_06_17", + "label": "[0.9.0] \u2014 2026-06-17", + "_origin": "ast", + "community": 116, + "community_name": "[0.9.0] \u2014 2026-06-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.9.0] \u2014 2026-06-17", + "source_file": "CHANGELOG.md", + "source_location": "L602" + }, + { + "id": "changelog_added_604", + "label": "Added", + "_origin": "ast", + "community": 116, + "community_name": "[0.9.0] \u2014 2026-06-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L604" + }, + { + "id": "changelog_compatibility_607", + "label": "Compatibility", + "_origin": "ast", + "community": 116, + "community_name": "[0.9.0] \u2014 2026-06-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L607" + }, + { + "id": "claude", + "label": "CLAUDE.md", + "_origin": "ast", + "community": 117, + "community_name": "Project conventions \u2014 session-continuity", + "file_type": "document", + "node_kind": "page", + "norm_label": "claude.md", + "source_file": "CLAUDE.md", + "source_location": "L1" + }, + { + "id": "claude_agent_meta_artifacts_go_under_meta_superpowers_not_docs", + "label": "Agent meta-artifacts go under `meta/superpowers/`, not `docs/`", + "_origin": "ast", + "community": 117, + "community_name": "Project conventions \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "agent meta-artifacts go under `meta/superpowers/`, not `docs/`", + "source_file": "CLAUDE.md", + "source_location": "L6" + }, + { + "id": "claude_project_conventions_session_continuity", + "label": "Project conventions \u2014 session-continuity", + "_origin": "ast", + "community": 117, + "community_name": "Project conventions \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "project conventions \u2014 session-continuity", + "source_file": "CLAUDE.md", + "source_location": "L1" + }, + { + "id": "hooks_lib_backlog_issues", + "label": "backlog-issues.sh", + "_origin": "ast", + "community": 118, + "community_name": "backlog-issues.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "backlog-issues.sh", + "source_file": "hooks/lib/backlog-issues.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_backlog_issues_fail_open", + "label": "fail_open()", + "_origin": "ast", + "community": 118, + "community_name": "backlog-issues.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "fail_open()", + "source_file": "hooks/lib/backlog-issues.sh", + "source_location": "L35" + }, + { + "id": "hooks_lib_backlog_issues_sh__entry", + "label": "backlog-issues.sh script", + "_origin": "ast", + "community": 118, + "community_name": "backlog-issues.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "backlog-issues.sh script", + "source_file": "hooks/lib/backlog-issues.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_candidate_render", + "label": "candidate-render.sh", + "_origin": "ast", + "community": 119, + "community_name": "candidate-render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "candidate-render.sh", + "source_file": "hooks/lib/candidate-render.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_candidate_render_fallback", + "label": "fallback()", + "_origin": "ast", + "community": 119, + "community_name": "candidate-render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "fallback()", + "source_file": "hooks/lib/candidate-render.sh", + "source_location": "L29" + }, + { + "id": "hooks_lib_candidate_render_sh__entry", + "label": "candidate-render.sh script", + "_origin": "ast", + "community": 119, + "community_name": "candidate-render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "candidate-render.sh script", + "source_file": "hooks/lib/candidate-render.sh", + "source_location": "L1" + }, + { + "id": "commands_end_session", + "label": "end-session.md", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "frontmatter": { + "description": "Refresh the primer, surface LEARNINGS candidates from this session, and report a close-out checklist. Zero args." + }, + "node_kind": "page", + "norm_label": "end-session.md", + "source_file": "commands/end-session.md", + "source_location": "L1" + }, + { + "id": "commands_end_session_backlog_verification_gated_by_commit_subject_overlap", + "label": "Backlog verification (gated by commit-subject overlap)", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "backlog verification (gated by commit-subject overlap)", + "source_file": "commands/end-session.md", + "source_location": "L62" + }, + { + "id": "commands_end_session_capture_flow_batch_presentation_single_confirm", + "label": "Capture flow \u2014 batch presentation, single confirm", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "capture flow \u2014 batch presentation, single confirm", + "source_file": "commands/end-session.md", + "source_location": "L426" + }, + { + "id": "commands_end_session_fast_path_nothing_changed_since_last_close_out_check_first_cheap", + "label": "Fast path \u2014 nothing changed since last close-out (check first, cheap)", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fast path \u2014 nothing changed since last close-out (check first, cheap)", + "source_file": "commands/end-session.md", + "source_location": "L34" + }, + { + "id": "commands_end_session_freshness_check_silent_no_user_prompt", + "label": "Freshness check (silent \u2014 no user prompt)", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "freshness check (silent \u2014 no user prompt)", + "source_file": "commands/end-session.md", + "source_location": "L214" + }, + { + "id": "commands_end_session_freshness_clean_close_candidate_prompt_runs_only_when_stale_0_and_1_appears_done_item", + "label": "Freshness-clean close-candidate prompt (runs only when `STALE=0` AND \u22651 `appears-DONE` item)", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "freshness-clean close-candidate prompt (runs only when `stale=0` and \u22651 `appears-done` item)", + "source_file": "commands/end-session.md", + "source_location": "L251" + }, + { + "id": "commands_end_session_gather_the_facts_and_render", + "label": "Gather the facts and render", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "gather the facts and render", + "source_file": "commands/end-session.md", + "source_location": "L479" + }, + { + "id": "commands_end_session_notes", + "label": "Notes", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "notes", + "source_file": "commands/end-session.md", + "source_location": "L621" + }, + { + "id": "commands_end_session_output", + "label": "Output", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "output", + "source_file": "commands/end-session.md", + "source_location": "L396" + }, + { + "id": "commands_end_session_privacy", + "label": "Privacy", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "privacy", + "source_file": "commands/end-session.md", + "source_location": "L390" + }, + { + "id": "commands_end_session_refresh_flow_runs_when_stale_1_or_stale", + "label": "Refresh flow (runs when `STALE=1` or `STALE=?`)", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "refresh flow (runs when `stale=1` or `stale=?`)", + "source_file": "commands/end-session.md", + "source_location": "L275" + }, + { + "id": "commands_end_session_resolve_extract_and_render", + "label": "Resolve, extract, and render", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "resolve, extract, and render", + "source_file": "commands/end-session.md", + "source_location": "L357" + }, + { + "id": "commands_end_session_session_continuity_end_session", + "label": "/session-continuity:end-session", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:end-session", + "source_file": "commands/end-session.md", + "source_location": "L5" + }, + { + "id": "commands_end_session_step_0_preconditions", + "label": "Step 0 \u2014 Preconditions", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 0 \u2014 preconditions", + "source_file": "commands/end-session.md", + "source_location": "L13" + }, + { + "id": "commands_end_session_step_1_refresh_the_primer_freshness_gated", + "label": "Step 1 \u2014 Refresh the primer (freshness-gated)", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 \u2014 refresh the primer (freshness-gated)", + "source_file": "commands/end-session.md", + "source_location": "L26" + }, + { + "id": "commands_end_session_step_2_session_reflection_for_learnings", + "label": "Step 2 \u2014 Session reflection for learnings", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 \u2014 session reflection for learnings", + "source_file": "commands/end-session.md", + "source_location": "L351" + }, + { + "id": "commands_end_session_step_3_final_checklist", + "label": "Step 3 \u2014 Final checklist", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3 \u2014 final checklist", + "source_file": "commands/end-session.md", + "source_location": "L473" + }, + { + "id": "commands_end_session_step_4_ritual_timing_always", + "label": "Step 4 \u2014 Ritual timing (always)", + "_origin": "ast", + "community": 12, + "community_name": "/session-continuity:end-session", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 4 \u2014 ritual timing (always)", + "source_file": "commands/end-session.md", + "source_location": "L562" + }, + { + "id": "hooks_lib_checklist_assemble", + "label": "checklist-assemble.sh", + "_origin": "ast", + "community": 120, + "community_name": "checklist-assemble.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "checklist-assemble.sh", + "source_file": "hooks/lib/checklist-assemble.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_checklist_assemble_fallback", + "label": "fallback()", + "_origin": "ast", + "community": 120, + "community_name": "checklist-assemble.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "fallback()", + "source_file": "hooks/lib/checklist-assemble.sh", + "source_location": "L24" + }, + { + "id": "hooks_lib_checklist_assemble_sh__entry", + "label": "checklist-assemble.sh script", + "_origin": "ast", + "community": 120, + "community_name": "checklist-assemble.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "checklist-assemble.sh script", + "source_file": "hooks/lib/checklist-assemble.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_init_derive", + "label": "primer-init-derive.sh", + "_origin": "ast", + "community": 121, + "community_name": "primer-init-derive.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "primer-init-derive.sh", + "source_file": "hooks/lib/primer-init-derive.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_init_derive_die", + "label": "die()", + "_origin": "ast", + "community": 121, + "community_name": "primer-init-derive.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "die()", + "source_file": "hooks/lib/primer-init-derive.sh", + "source_location": "L32" + }, + { + "id": "hooks_lib_primer_init_derive_sh__entry", + "label": "primer-init-derive.sh script", + "_origin": "ast", + "community": 121, + "community_name": "primer-init-derive.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "primer-init-derive.sh script", + "source_file": "hooks/lib/primer-init-derive.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_require_script", + "label": "require-script.sh", + "_origin": "ast", + "community": 122, + "community_name": "require-script.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "require-script.sh", + "source_file": "hooks/lib/require-script.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_require_script_require_script", + "label": "require_script()", + "_origin": "ast", + "community": 122, + "community_name": "require-script.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "require_script()", + "source_file": "hooks/lib/require-script.sh", + "source_location": "L16" + }, + { + "id": "hooks_lib_require_script_sh__entry", + "label": "require-script.sh script", + "_origin": "ast", + "community": 122, + "community_name": "require-script.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "require-script.sh script", + "source_file": "hooks/lib/require-script.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_resolve_transcript", + "label": "resolve-transcript.sh", + "_origin": "ast", + "community": 123, + "community_name": "resolve-transcript.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "resolve-transcript.sh", + "source_file": "hooks/lib/resolve-transcript.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_resolve_transcript_mtime_epoch", + "label": "mtime_epoch()", + "_origin": "ast", + "community": 123, + "community_name": "resolve-transcript.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "mtime_epoch()", + "source_file": "hooks/lib/resolve-transcript.sh", + "source_location": "L26" + }, + { + "id": "hooks_lib_resolve_transcript_sh__entry", + "label": "resolve-transcript.sh script", + "_origin": "ast", + "community": 123, + "community_name": "resolve-transcript.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "resolve-transcript.sh script", + "source_file": "hooks/lib/resolve-transcript.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_token_overlap", + "label": "token-overlap.sh", + "_origin": "ast", + "community": 124, + "community_name": "token-overlap.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "token-overlap.sh", + "source_file": "hooks/lib/token-overlap.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_token_overlap_die", + "label": "die()", + "_origin": "ast", + "community": 124, + "community_name": "token-overlap.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "die()", + "source_file": "hooks/lib/token-overlap.sh", + "source_location": "L34" + }, + { + "id": "hooks_lib_token_overlap_sh__entry", + "label": "token-overlap.sh script", + "_origin": "ast", + "community": 124, + "community_name": "token-overlap.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "token-overlap.sh script", + "source_file": "hooks/lib/token-overlap.sh", + "source_location": "L1" + }, + { + "id": "hooks_version_check", + "label": "version-check.sh", + "_origin": "ast", + "community": 125, + "community_name": "version-check.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "version-check.sh", + "source_file": "hooks/version-check.sh", + "source_location": "L1" + }, + { + "id": "hooks_version_check_json_field", + "label": "json_field()", + "_origin": "ast", + "community": 125, + "community_name": "version-check.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "json_field()", + "source_file": "hooks/version-check.sh", + "source_location": "L90" + }, + { + "id": "hooks_version_check_sh__entry", + "label": "version-check.sh script", + "_origin": "ast", + "community": 125, + "community_name": "version-check.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "version-check.sh script", + "source_file": "hooks/version-check.sh", + "source_location": "L1" + }, + { + "id": "changelog_0_13_0_2026_08_13", + "label": "[0.13.0] \u2014 2026-08-13", + "_origin": "ast", + "community": 126, + "community_name": "[0.13.0] \u2014 2026-08-13", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.13.0] \u2014 2026-08-13", + "source_file": "CHANGELOG.md", + "source_location": "L488" + }, + { + "id": "changelog_added_490", + "label": "Added", + "_origin": "ast", + "community": 126, + "community_name": "[0.13.0] \u2014 2026-08-13", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L490" + }, + { + "id": "changelog_0_14_1_2026_08_13", + "label": "[0.14.1] \u2014 2026-08-13", + "_origin": "ast", + "community": 127, + "community_name": "[0.14.1] \u2014 2026-08-13", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.14.1] \u2014 2026-08-13", + "source_file": "CHANGELOG.md", + "source_location": "L434" + }, + { + "id": "changelog_fixed_436", + "label": "Fixed", + "_origin": "ast", + "community": 127, + "community_name": "[0.14.1] \u2014 2026-08-13", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L436" + }, + { + "id": "changelog_0_15_0_2026_08_17", + "label": "[0.15.0] \u2014 2026-08-17", + "_origin": "ast", + "community": 128, + "community_name": "[0.15.0] \u2014 2026-08-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.15.0] \u2014 2026-08-17", + "source_file": "CHANGELOG.md", + "source_location": "L336" + }, + { + "id": "changelog_added_338", + "label": "Added", + "_origin": "ast", + "community": 128, + "community_name": "[0.15.0] \u2014 2026-08-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L338" + }, + { + "id": "changelog_0_15_1_2026_08_17", + "label": "[0.15.1] \u2014 2026-08-17", + "_origin": "ast", + "community": 129, + "community_name": "[0.15.1] \u2014 2026-08-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.15.1] \u2014 2026-08-17", + "source_file": "CHANGELOG.md", + "source_location": "L316" + }, + { + "id": "changelog_fixed_318", + "label": "Fixed", + "_origin": "ast", + "community": 129, + "community_name": "[0.15.1] \u2014 2026-08-17", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L318" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "label": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_already_decided_above_not_auto_verifiable_for_non_code_items_no", + "label": "already decided above \u2014 \"not auto-verifiable\" for non-code items, \"no", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "already decided above \u2014 \"not auto-verifiable\" for non-code items, \"no", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L615" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_determinism_phase_4_end_session_step_3_checklist_assembly_implementation_plan", + "label": "Determinism Phase 4 \u2014 `end-session` Step 3 checklist assembly \u2014 Implementation Plan", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 4 \u2014 `end-session` step 3 checklist assembly \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L25" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_n_identity_never_the_ephemeral_1_n_list_position_verdict_second", + "label": "#N identity, never the ephemeral 1..N list position), verdict second", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "#n identity, never the ephemeral 1..n list position), verdict second", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L613" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_one_such_literal_printf_line_per_remaining_open_item_tag_first_the", + "label": "... one such literal printf line per remaining open item, tag first (the", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "... one such literal printf line per remaining open item, tag first (the", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L612" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_overlap_gated_ones", + "label": "overlap-gated ones) ...", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "overlap-gated ones) ...", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L617" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_primer_learnings_json_commit_subject_json_set_these_three_from_what", + "label": "PRIMER, LEARNINGS_JSON, COMMIT_SUBJECT_JSON: set these three from what", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "primer, learnings_json, commit_subject_json: set these three from what", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L794" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_related_commits_since_last_refresh_not_re_checked_this_session_for", + "label": "related commits since last refresh \u2014 not re-checked this session\" for", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "related commits since last refresh \u2014 not re-checked this session\" for", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L616" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_step_1_step_2_actually_did_this_invocation_see_the_field_notes_below", + "label": "Step 1/Step 2 actually did this invocation \u2014 see the field notes below.", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1/step 2 actually did this invocation \u2014 see the field notes below.", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L795" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_still_open_appears_done_manual_citation_third_the_same_evidence_string", + "label": "(still-open|appears-DONE|manual), citation third (the same evidence string", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "(still-open|appears-done|manual), citation third (the same evidence string", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L614" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_1_hooks_lib_checklist_assemble_sh", + "label": "Task 1: `hooks/lib/checklist-assemble.sh`", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `hooks/lib/checklist-assemble.sh`", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L38" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_2_perf_log_sh_gitignore_the_new_scratch_tsv", + "label": "Task 2: `perf-log.sh` \u2014 gitignore the new scratch TSV", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `perf-log.sh` \u2014 gitignore the new scratch tsv", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L512" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_3_commands_end_session_md_step_1_fast_path_count_and_the_backlog_verdict_tsv", + "label": "Task 3: `commands/end-session.md` Step 1 \u2014 fast-path count and the backlog-verdict TSV", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: `commands/end-session.md` step 1 \u2014 fast-path count and the backlog-verdict tsv", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L553" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_4_commands_end_session_md_step_3_call_checklist_assemble_sh", + "label": "Task 4: `commands/end-session.md` Step 3 \u2014 call `checklist-assemble.sh`", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: `commands/end-session.md` step 3 \u2014 call `checklist-assemble.sh`", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L642" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_5_commands_end_session_md_step_4_drop_the_printed_sign_off_keep_only_timing", + "label": "Task 5: `commands/end-session.md` Step 4 \u2014 drop the printed sign-off, keep only timing", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: `commands/end-session.md` step 4 \u2014 drop the printed sign-off, keep only timing", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L857" + }, + { + "id": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_6_doc_pointers_regression_pass_changelog", + "label": "Task 6: Doc pointers, regression pass, changelog", + "_origin": "ast", + "community": 13, + "community_name": "2026-09-08-determinism-phase-4-checklist-assembly.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: doc pointers, regression pass, changelog", + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L931" + }, + { + "id": "changelog_0_20_0_2026_08_31", + "label": "[0.20.0] \u2014 2026-08-31", + "_origin": "ast", + "community": 130, + "community_name": "[0.20.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.20.0] \u2014 2026-08-31", + "source_file": "CHANGELOG.md", + "source_location": "L166" + }, + { + "id": "changelog_added_168", + "label": "Added", + "_origin": "ast", + "community": 130, + "community_name": "[0.20.0] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L168" + }, + { + "id": "changelog_0_21_1_2026_08_31", + "label": "[0.21.1] \u2014 2026-08-31", + "_origin": "ast", + "community": 131, + "community_name": "[0.21.1] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.21.1] \u2014 2026-08-31", + "source_file": "CHANGELOG.md", + "source_location": "L153" + }, + { + "id": "changelog_fixed_155", + "label": "Fixed", + "_origin": "ast", + "community": 131, + "community_name": "[0.21.1] \u2014 2026-08-31", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L155" + }, + { + "id": "changelog_0_27_0_2026_09_02", + "label": "[0.27.0] \u2014 2026-09-02", + "_origin": "ast", + "community": 132, + "community_name": "[0.27.0] \u2014 2026-09-02", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.27.0] \u2014 2026-09-02", + "source_file": "CHANGELOG.md", + "source_location": "L88" + }, + { + "id": "changelog_changed_90", + "label": "Changed", + "_origin": "ast", + "community": 132, + "community_name": "[0.27.0] \u2014 2026-09-02", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L90" + }, + { + "id": "changelog_0_28_0_2026_09_03", + "label": "[0.28.0] \u2014 2026-09-03", + "_origin": "ast", + "community": 133, + "community_name": "[0.28.0] \u2014 2026-09-03", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.28.0] \u2014 2026-09-03", + "source_file": "CHANGELOG.md", + "source_location": "L76" + }, + { + "id": "changelog_changed_78", + "label": "Changed", + "_origin": "ast", + "community": 133, + "community_name": "[0.28.0] \u2014 2026-09-03", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L78" + }, + { + "id": "changelog_0_29_1_2026_09_07", + "label": "[0.29.1] \u2014 2026-09-07", + "_origin": "ast", + "community": 134, + "community_name": "[0.29.1] \u2014 2026-09-07", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.29.1] \u2014 2026-09-07", + "source_file": "CHANGELOG.md", + "source_location": "L58" + }, + { + "id": "changelog_fixed_60", + "label": "Fixed", + "_origin": "ast", + "community": 134, + "community_name": "[0.29.1] \u2014 2026-09-07", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L60" + }, + { + "id": "changelog_0_30_0_2026_09_08", + "label": "[0.30.0] \u2014 2026-09-08", + "_origin": "ast", + "community": 135, + "community_name": "[0.30.0] \u2014 2026-09-08", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.30.0] \u2014 2026-09-08", + "source_file": "CHANGELOG.md", + "source_location": "L53" + }, + { + "id": "changelog_changed_55", + "label": "Changed", + "_origin": "ast", + "community": 135, + "community_name": "[0.30.0] \u2014 2026-09-08", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L55" + }, + { + "id": "changelog_0_32_0_2026_09_08", + "label": "[0.32.0] \u2014 2026-09-08", + "_origin": "ast", + "community": 136, + "community_name": "[0.32.0] \u2014 2026-09-08", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.32.0] \u2014 2026-09-08", + "source_file": "CHANGELOG.md", + "source_location": "L43" + }, + { + "id": "changelog_changed_45", + "label": "Changed", + "_origin": "ast", + "community": 136, + "community_name": "[0.32.0] \u2014 2026-09-08", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L45" + }, + { + "id": "changelog_0_34_0_2026_09_09", + "label": "[0.34.0] \u2014 2026-09-09", + "_origin": "ast", + "community": 137, + "community_name": "[0.34.0] \u2014 2026-09-09", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.34.0] \u2014 2026-09-09", + "source_file": "CHANGELOG.md", + "source_location": "L22" + }, + { + "id": "changelog_changed", + "label": "Changed", + "_origin": "ast", + "community": 137, + "community_name": "[0.34.0] \u2014 2026-09-09", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L24" + }, + { + "id": "commands_backlog", + "label": "backlog.md", + "_origin": "ast", + "community": 138, + "community_name": "backlog.md", + "file_type": "document", + "frontmatter": { + "description": "List open GitHub Issues labeled backlog. Zero args, read-only." + }, + "node_kind": "page", + "norm_label": "backlog.md", + "source_file": "commands/backlog.md", + "source_location": "L1" + }, + { + "id": "commands_backlog_session_continuity_backlog", + "label": "/session-continuity:backlog", + "_origin": "ast", + "community": 138, + "community_name": "backlog.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:backlog", + "source_file": "commands/backlog.md", + "source_location": "L5" + }, + { + "id": "commands_help", + "label": "help.md", + "_origin": "ast", + "community": 139, + "community_name": "help.md", + "file_type": "document", + "frontmatter": { + "description": "Explain what this plugin does, why, and what each `.session-continuity/` file is for. Zero args, read-only, no state mutation." + }, + "node_kind": "page", + "norm_label": "help.md", + "source_file": "commands/help.md", + "source_location": "L1" + }, + { + "id": "commands_help_session_continuity_help", + "label": "/session-continuity:help", + "_origin": "ast", + "community": 139, + "community_name": "help.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:help", + "source_file": "commands/help.md", + "source_location": "L5" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help", + "label": "2026-08-31-backlog-roadmap-help.md", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-31-backlog-roadmap-help.md", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_backlog_roadmap_rename_session_continuity_help_implementation_plan", + "label": "BACKLOG/ROADMAP rename + /session-continuity:help Implementation Plan", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "backlog/roadmap rename + /session-continuity:help implementation plan", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_10_templates_claude_md_snippet_md_and_session_primer_md_rename_add_roadmap", + "label": "Task 10: Templates `CLAUDE_MD_SNIPPET.md` and `SESSION_PRIMER.md` \u2014 rename + add ROADMAP", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 10: templates `claude_md_snippet.md` and `session_primer.md` \u2014 rename + add roadmap", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L869" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_11_plugin_json_version_bump_privacy_md_contributing_md_changelog_md", + "label": "Task 11: `plugin.json` version bump, `PRIVACY.md`, `CONTRIBUTING.md`, `CHANGELOG.md`", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 11: `plugin.json` version bump, `privacy.md`, `contributing.md`, `changelog.md`", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L951" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_12_readme_md_full_rename_five_file_language_help_command", + "label": "Task 12: `README.md` \u2014 full rename + five-file language + help command", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 12: `readme.md` \u2014 full rename + five-file language + help command", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1070" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_13_dogfood_migrate_this_repo_s_own_session_continuity_instance", + "label": "Task 13: Dogfood \u2014 migrate this repo's own `.session-continuity/` instance", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 13: dogfood \u2014 migrate this repo's own `.session-continuity/` instance", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1255" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_14_final_full_repo_verification_and_pr", + "label": "Task 14: Final full-repo verification and PR", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 14: final full-repo verification and pr", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1347" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_1_rename_template_outstanding_items_md_backlog_md", + "label": "Task 1: Rename template `OUTSTANDING_ITEMS.md` \u2192 `BACKLOG.md`", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: rename template `outstanding_items.md` \u2192 `backlog.md`", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L23" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_2_new_template_roadmap_md", + "label": "Task 2: New template `ROADMAP.md`", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: new template `roadmap.md`", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L79" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_3_new_command_session_continuity_help", + "label": "Task 3: New command `/session-continuity:help`", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: new command `/session-continuity:help`", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L128" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_4_hooks_session_start_sh_rename_migration_nudge_branch", + "label": "Task 4: `hooks/session-start.sh` \u2014 rename + migration-nudge branch", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: `hooks/session-start.sh` \u2014 rename + migration-nudge branch", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L231" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_5_commands_primer_md_detection_init_mode_migration_step_3c_placeholder_rename", + "label": "Task 5: `commands/primer.md` \u2014 detection, init mode, migration Step 3c, placeholder rename", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: `commands/primer.md` \u2014 detection, init mode, migration step 3c, placeholder rename", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L382" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_6_commands_doctor_md_track_backlog_md_and_roadmap_md", + "label": "Task 6: `commands/doctor.md` \u2014 track BACKLOG.md and ROADMAP.md", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: `commands/doctor.md` \u2014 track backlog.md and roadmap.md", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L582" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_7_commands_end_session_md_rename_throughout", + "label": "Task 7: `commands/end-session.md` \u2014 rename throughout", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: `commands/end-session.md` \u2014 rename throughout", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L638" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_8_skills_session_continuity_skill_md_rename_five_files_add_help_command", + "label": "Task 8: `skills/session-continuity/SKILL.md` \u2014 rename, five files, add help command", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: `skills/session-continuity/skill.md` \u2014 rename, five files, add help command", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L692" + }, + { + "id": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_9_skills_session_continuity_reference_md_rename", + "label": "Task 9: `skills/session-continuity/REFERENCE.md` \u2014 rename", + "_origin": "ast", + "community": 14, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 9: `skills/session-continuity/reference.md` \u2014 rename", + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L814" + }, + { + "id": "commands_learnings", + "label": "learnings.md", + "_origin": "ast", + "community": 140, + "community_name": "learnings.md", + "file_type": "document", + "frontmatter": { + "description": "List .session-continuity/LEARNINGS.md's entries. Zero args, read-only." + }, + "node_kind": "page", + "norm_label": "learnings.md", + "source_file": "commands/learnings.md", + "source_location": "L1" + }, + { + "id": "commands_learnings_session_continuity_learnings", + "label": "/session-continuity:learnings", + "_origin": "ast", + "community": 140, + "community_name": "learnings.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:learnings", + "source_file": "commands/learnings.md", + "source_location": "L5" + }, + { + "id": "commands_update", + "label": "update.md", + "_origin": "ast", + "community": 141, + "community_name": "update.md", + "file_type": "document", + "frontmatter": { + "description": "Print the exact commands to update this plugin to its latest published version. Zero args, no execution \u2014 the assistant cannot invoke /plugin or /reload-plugins itself." + }, + "node_kind": "page", + "norm_label": "update.md", + "source_file": "commands/update.md", + "source_location": "L1" + }, + { + "id": "commands_update_session_continuity_update", + "label": "/session-continuity:update", + "_origin": "ast", + "community": 141, + "community_name": "update.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:update", + "source_file": "commands/update.md", + "source_location": "L5" + }, + { + "id": "githooks_pre_commit", + "label": "pre-commit", + "_origin": "ast", + "community": 142, + "community_name": "pre-commit", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "pre-commit", + "source_file": ".githooks/pre-commit", + "source_location": "L1" + }, + { + "id": "githooks_pre_commit__entry", + "label": "pre-commit script", + "_origin": "ast", + "community": 142, + "community_name": "pre-commit", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "pre-commit script", + "source_file": ".githooks/pre-commit", + "source_location": "L1" + }, + { + "id": "hooks_learnings_surface", + "label": "learnings-surface.sh", + "_origin": "ast", + "community": 143, + "community_name": "learnings-surface.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "learnings-surface.sh", + "source_file": "hooks/learnings-surface.sh", + "source_location": "L1" + }, + { + "id": "hooks_learnings_surface_sh__entry", + "label": "learnings-surface.sh script", + "_origin": "ast", + "community": 143, + "community_name": "learnings-surface.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "learnings-surface.sh script", + "source_file": "hooks/learnings-surface.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_agent_active", + "label": "agent-active.sh", + "_origin": "ast", + "community": 144, + "community_name": "agent-active.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "agent-active.sh", + "source_file": "hooks/lib/agent-active.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_agent_active_sh__entry", + "label": "agent-active.sh script", + "_origin": "ast", + "community": 144, + "community_name": "agent-active.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "agent-active.sh script", + "source_file": "hooks/lib/agent-active.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_count_entries", + "label": "count-entries.sh", + "_origin": "ast", + "community": 145, + "community_name": "count-entries.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "count-entries.sh", + "source_file": "hooks/lib/count-entries.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_count_entries_sh__entry", + "label": "count-entries.sh script", + "_origin": "ast", + "community": 145, + "community_name": "count-entries.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "count-entries.sh script", + "source_file": "hooks/lib/count-entries.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_peer_probes", + "label": "peer-probes.sh", + "_origin": "ast", + "community": 146, + "community_name": "peer-probes.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "peer-probes.sh", + "source_file": "hooks/lib/peer-probes.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_peer_probes_sh__entry", + "label": "peer-probes.sh script", + "_origin": "ast", + "community": 146, + "community_name": "peer-probes.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "peer-probes.sh script", + "source_file": "hooks/lib/peer-probes.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_perf_wrap", + "label": "perf-wrap.sh", + "_origin": "ast", + "community": 147, + "community_name": "perf-wrap.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "perf-wrap.sh", + "source_file": "hooks/lib/perf-wrap.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_perf_wrap_sh__entry", + "label": "perf-wrap.sh script", + "_origin": "ast", + "community": 147, + "community_name": "perf-wrap.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "perf-wrap.sh script", + "source_file": "hooks/lib/perf-wrap.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_freshness", + "label": "primer-freshness.sh", + "_origin": "ast", + "community": 148, + "community_name": "primer-freshness.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "primer-freshness.sh", + "source_file": "hooks/lib/primer-freshness.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_freshness_sh__entry", + "label": "primer-freshness.sh script", + "_origin": "ast", + "community": 148, + "community_name": "primer-freshness.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "primer-freshness.sh script", + "source_file": "hooks/lib/primer-freshness.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_status", + "label": "primer-status.sh", + "_origin": "ast", + "community": 149, + "community_name": "primer-status.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "primer-status.sh", + "source_file": "hooks/lib/primer-status.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_status_sh__entry", + "label": "primer-status.sh script", + "_origin": "ast", + "community": 149, + "community_name": "primer-status.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "primer-status.sh script", + "source_file": "hooks/lib/primer-status.sh", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design", + "label": "2026-06-15-fire-before-action-design.md", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-06-15-fire-before-action-design.md", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_a_learnings_retrieval_hook", + "label": "Component A \u2014 LEARNINGS retrieval hook", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "component a \u2014 learnings retrieval hook", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L51" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_b_smoke_gate_hook", + "label": "Component B \u2014 smoke-gate hook", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "component b \u2014 smoke-gate hook", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L112" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_cross_cutting", + "label": "Cross-cutting", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "cross-cutting", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L156" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_entry_trigger_syntax", + "label": "Entry trigger syntax", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "entry trigger syntax", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L53" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_escape_hatch", + "label": "Escape hatch", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "escape hatch", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L141" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "label": "Fire Before the Action \u2014 session-continuity v0.8.0", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fire before the action \u2014 session-continuity v0.8.0", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_goals", + "label": "Goals", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goals", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L29" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_hook_ordering", + "label": "Hook ordering", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hook ordering", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L149" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_hooks_learnings_surface_sh", + "label": "`hooks/learnings-surface.sh`", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/learnings-surface.sh`", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L74" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_hooks_smoke_gate_sh", + "label": "`hooks/smoke-gate.sh`", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/smoke-gate.sh`", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L114" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_learning_command_change", + "label": "`/learning` command change", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/learning` command change", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L95" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L40" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L3" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_template_change", + "label": "Template change", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "template change", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L107" + }, + { + "id": "meta_superpowers_specs_2026_06_15_fire_before_action_design_testing_this_plugin_smokes_itself", + "label": "Testing (this plugin smokes itself)", + "_origin": "ast", + "community": 15, + "community_name": "Fire Before the Action \u2014 session-continuity v0.8.0", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing (this plugin smokes itself)", + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L168" + }, + { + "id": "hooks_lib_primer_validate", + "label": "primer-validate.sh", + "_origin": "ast", + "community": 150, + "community_name": "primer-validate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "primer-validate.sh", + "source_file": "hooks/lib/primer-validate.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_validate_sh__entry", + "label": "primer-validate.sh script", + "_origin": "ast", + "community": 150, + "community_name": "primer-validate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "primer-validate.sh script", + "source_file": "hooks/lib/primer-validate.sh", + "source_location": "L1" + }, + { + "id": "hooks_pre_commit_check", + "label": "pre-commit-check.sh", + "_origin": "ast", + "community": 151, + "community_name": "pre-commit-check.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "pre-commit-check.sh", + "source_file": "hooks/pre-commit-check.sh", + "source_location": "L1" + }, + { + "id": "hooks_pre_commit_check_sh__entry", + "label": "pre-commit-check.sh script", + "_origin": "ast", + "community": 151, + "community_name": "pre-commit-check.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "pre-commit-check.sh script", + "source_file": "hooks/pre-commit-check.sh", + "source_location": "L1" + }, + { + "id": "hooks_prompt_intercept", + "label": "prompt-intercept.sh", + "_origin": "ast", + "community": 152, + "community_name": "prompt-intercept.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "prompt-intercept.sh", + "source_file": "hooks/prompt-intercept.sh", + "source_location": "L1" + }, + { + "id": "hooks_prompt_intercept_sh__entry", + "label": "prompt-intercept.sh script", + "_origin": "ast", + "community": 152, + "community_name": "prompt-intercept.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "prompt-intercept.sh script", + "source_file": "hooks/prompt-intercept.sh", + "source_location": "L1" + }, + { + "id": "hooks_session_start", + "label": "session-start.sh", + "_origin": "ast", + "community": 153, + "community_name": "session-start.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "session-start.sh", + "source_file": "hooks/session-start.sh", + "source_location": "L1" + }, + { + "id": "hooks_session_start_sh__entry", + "label": "session-start.sh script", + "_origin": "ast", + "community": 153, + "community_name": "session-start.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "session-start.sh script", + "source_file": "hooks/session-start.sh", + "source_location": "L1" + }, + { + "id": "meta_superpowers_validation_2026_09_08_token_overlap", + "label": "2026-09-08-token-overlap.md", + "_origin": "ast", + "community": 154, + "community_name": "2026-09-08-token-overlap.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-08-token-overlap.md", + "source_file": "meta/superpowers/validation/2026-09-08-token-overlap.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_validation_2026_09_08_token_overlap_validation_log_token_overlap_gate_consolidation_determinism_phase_5_42", + "label": "Validation log \u2014 token-overlap gate consolidation (Determinism Phase 5, #42)", + "_origin": "ast", + "community": 154, + "community_name": "2026-09-08-token-overlap.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "validation log \u2014 token-overlap gate consolidation (determinism phase 5, #42)", + "source_file": "meta/superpowers/validation/2026-09-08-token-overlap.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design", + "label": "2026-08-27-commit-time-content-gates-design.md", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-27-commit-time-content-gates-design.md", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_approach_selected", + "label": "Approach (selected)", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "approach (selected)", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L53" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_components", + "label": "Components", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "components", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L73" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_decisions_from_brainstorming", + "label": "Decisions (from brainstorming)", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "decisions (from brainstorming)", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L44" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "label": "Design \u2014 commit-time content gates + false-trigger reduction", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design \u2014 commit-time content gates + false-trigger reduction", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_docs_version", + "label": "Docs / version", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "docs / version", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L198" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_error_handling", + "label": "Error handling", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "error handling", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L166" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_false_trigger_reduction_problem_2", + "label": "False-trigger reduction (Problem 2)", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "false-trigger reduction (problem 2)", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L145" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_flaky_gate_sh_stays_dual", + "label": "`flaky-gate.sh` \u2014 stays dual", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`flaky-gate.sh` \u2014 stays dual", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L124" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_goal_invariant", + "label": "Goal / invariant", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goal / invariant", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L37" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_hooks_hooks_json_rewire", + "label": "`hooks/hooks.json` rewire", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/hooks.json` rewire", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L133" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_hooks_lib_gate_common_sh_new_sourced", + "label": "`hooks/lib/gate-common.sh` (new, sourced)", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/lib/gate-common.sh` (new, sourced)", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L75" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_per_gate_commit_mode", + "label": "Per-gate commit mode", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "per-gate commit mode", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L104" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L9" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L177" + }, + { + "id": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_tradeoffs_accepted", + "label": "Tradeoffs (accepted)", + "_origin": "ast", + "community": 16, + "community_name": "Design \u2014 commit-time content gates + false-trigger reduction", + "file_type": "document", + "node_kind": "heading", + "norm_label": "tradeoffs (accepted)", + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L210" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design", + "label": "2026-09-01-end-session-step2-cost-attribution-design.md", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-01-end-session-step2-cost-attribution-design.md", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_change_1_ship_the_extraction_and_the_heuristics_as_one_script", + "label": "Change 1 \u2014 ship the extraction and the heuristics as one script", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "change 1 \u2014 ship the extraction and the heuristics as one script", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L131" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_change_2_measure_agent_active_time_instead_of_guessing_at_it", + "label": "Change 2 \u2014 measure agent-active time instead of guessing at it", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "change 2 \u2014 measure agent-active time instead of guessing at it", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L162" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_change_3_ship_the_learnings_derivations_as_a_script", + "label": "Change 3 \u2014 ship the LEARNINGS derivations as a script", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "change 3 \u2014 ship the learnings derivations as a script", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L207" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_design", + "label": "Design", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L129" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "label": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-session step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_1_compute_only_counts_human_idle_as_compute", + "label": "Finding 1 \u2014 `compute-only` counts human idle as compute", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "finding 1 \u2014 `compute-only` counts human idle as compute", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L28" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_2_the_real_step_2_cost_is_sequential_re_filtering", + "label": "Finding 2 \u2014 the real Step 2 cost is sequential re-filtering", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "finding 2 \u2014 the real step 2 cost is sequential re-filtering", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L75" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_3_the_shipped_shell_work_is_free", + "label": "Finding 3 \u2014 the shipped shell work is free", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "finding 3 \u2014 the shipped shell work is free", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L91" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_4_the_derived_content_steps_are_not_running_at_scale", + "label": "Finding 4 \u2014 the derived-content steps are not running at scale", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "finding 4 \u2014 the derived-content steps are not running at scale", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L102" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_invariants", + "label": "Invariants", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "invariants", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L114" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L223" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L14" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_resolved_decisions", + "label": "Resolved decisions", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "resolved decisions", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L269" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_testing_plan_nothing_here_is_implemented_yet", + "label": "Testing plan (nothing here is implemented yet)", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing plan (nothing here is implemented yet)", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L230" + }, + { + "id": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_what_the_measurement_shows", + "label": "What the measurement shows", + "_origin": "ast", + "community": 17, + "community_name": "End-session Step 2 \u2014 cost attribution and heuristic execution \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what the measurement shows", + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L26" + }, + { + "id": "hooks_lib_gate_common", + "label": "gate-common.sh", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "gate-common.sh", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_gate_common_deny", + "label": "deny()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "deny()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L97" + }, + { + "id": "hooks_lib_gate_common_gate_command", + "label": "gate_command()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_command()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L15" + }, + { + "id": "hooks_lib_gate_common_gate_field", + "label": "gate_field()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_field()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L7" + }, + { + "id": "hooks_lib_gate_common_gate_first_match", + "label": "gate_first_match()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_first_match()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L88" + }, + { + "id": "hooks_lib_gate_common_gate_has_escape", + "label": "gate_has_escape()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_has_escape()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L54" + }, + { + "id": "hooks_lib_gate_common_gate_is_commit", + "label": "gate_is_commit()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_is_commit()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L30" + }, + { + "id": "hooks_lib_gate_common_gate_is_scratch", + "label": "gate_is_scratch()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_is_scratch()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L46" + }, + { + "id": "hooks_lib_gate_common_gate_load", + "label": "gate_load()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_load()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L23" + }, + { + "id": "hooks_lib_gate_common_gate_mask_escape", + "label": "gate_mask_escape()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_mask_escape()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L63" + }, + { + "id": "hooks_lib_gate_common_gate_scan_staged", + "label": "gate_scan_staged()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_scan_staged()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L107" + }, + { + "id": "hooks_lib_gate_common_gate_staged_blob", + "label": "gate_staged_blob()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_staged_blob()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L42" + }, + { + "id": "hooks_lib_gate_common_gate_staged_files", + "label": "gate_staged_files()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_staged_files()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L36" + }, + { + "id": "hooks_lib_gate_common_json_escape", + "label": "json_escape()", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "json_escape()", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L93" + }, + { + "id": "hooks_lib_gate_common_sh__entry", + "label": "gate-common.sh script", + "_origin": "ast", + "community": 18, + "community_name": "gate-common.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "gate-common.sh script", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design", + "label": "2026-08-30-outstanding-items-file-design.md", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-30-outstanding-items-file-design.md", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_backward_compatibility", + "label": "Backward compatibility", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "backward compatibility", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L235" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_commands_end_session_md", + "label": "`commands/end-session.md`", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`commands/end-session.md`", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L145" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_commands_primer_md", + "label": "`commands/primer.md`", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`commands/primer.md`", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L182" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_consumer_changes", + "label": "Consumer changes", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "consumer changes", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L114" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_decisions_from_brainstorming", + "label": "Decisions (from brainstorming)", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "decisions (from brainstorming)", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L37" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "label": "Design: a standalone OUTSTANDING_ITEMS.md", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design: a standalone outstanding_items.md", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_file_session_continuity_outstanding_items_md", + "label": "File: `.session-continuity/OUTSTANDING_ITEMS.md`", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file: `.session-continuity/outstanding_items.md`", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L52" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_hooks_session_start_sh", + "label": "`hooks/session-start.sh`", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/session-start.sh`", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L116" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_item_shape", + "label": "Item shape", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "item shape", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L81" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_migration_of_this_repo", + "label": "Migration of this repo", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "migration of this repo", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L253" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L286" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L5" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_skill_md_templates_claude_md_snippet_md_readme_md", + "label": "`SKILL.md`, `templates/CLAUDE_MD_SNIPPET.md`, `README.md`", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`skill.md`, `templates/claude_md_snippet.md`, `readme.md`", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L216" + }, + { + "id": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 19, + "community_name": "Design: a standalone OUTSTANDING_ITEMS.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L262" + }, + { + "id": "session_continuity_learnings", + "label": ".session-continuity/LEARNINGS.md", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "page", + "norm_label": ".session-continuity/learnings.md", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L1" + }, + { + "id": "session_continuity_learnings_10_jq_s_split_n_0_returns_null_on_an_empty_string_crashes_the_next_gsub_in_a_chain", + "label": "10. jq's `split(\"\\n\")[0]` returns `null` on an empty string \u2014 crashes the next `gsub` in a chain", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "10. jq's `split(\"\\n\")[0]` returns `null` on an empty string \u2014 crashes the next `gsub` in a chain", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L158" + }, + { + "id": "session_continuity_learnings_11_claude_plugin_root_inside_a_bash_fence_in_a_skill_command_file_is_never_resolved_only_the_braced_claude_plugin_root_form_is", + "label": "11. `$CLAUDE_PLUGIN_ROOT` inside a bash fence in a skill/command file is never resolved \u2014 only the braced `${CLAUDE_PLUGIN_ROOT}` form is", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "11. `$claude_plugin_root` inside a bash fence in a skill/command file is never resolved \u2014 only the braced `${claude_plugin_root}` form is", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L67" + }, + { + "id": "session_continuity_learnings_12_a_smoke_test_s_own_hermeticity_bug_recurred_twice_in_two_unrelated_tasks_even_after_being_caught_and_fixed_once", + "label": "12. A smoke test's own hermeticity bug recurred twice, in two unrelated tasks, even after being caught and fixed once", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "12. a smoke test's own hermeticity bug recurred twice, in two unrelated tasks, even after being caught and fixed once", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L310" + }, + { + "id": "session_continuity_learnings_13_proven_gate_sh_and_similar_word_boundary_content_gates_re_fire_on_an_edit_even_when_a_valid_escape_hatch_line_already_exists_elsewhere_in_the_same_file", + "label": "13. `proven-gate.sh` (and similar word-boundary content gates) re-fire on an `Edit` even when a valid escape-hatch line already exists elsewhere in the same file", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "13. `proven-gate.sh` (and similar word-boundary content gates) re-fire on an `edit` even when a valid escape-hatch line already exists elsewhere in the same file", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L324" + }, + { + "id": "session_continuity_learnings_14_commit_time_content_gates_only_see_the_git_index_git_commit_a_pathspec_bypasses_the_scan", + "label": "14. Commit-time content gates only see the git index \u2014 `git commit -a` / pathspec bypasses the scan", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "14. commit-time content gates only see the git index \u2014 `git commit -a` / pathspec bypasses the scan", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L293" + }, + { + "id": "session_continuity_learnings_15_squash_merging_a_branch_descended_from_an_unpushed_local_commit_orphans_that_commit_and_any_tag_pointing_at_it", + "label": "15. Squash-merging a branch descended from an unpushed local commit orphans that commit \u2014 and any tag pointing at it", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "15. squash-merging a branch descended from an unpushed local commit orphans that commit \u2014 and any tag pointing at it", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L431" + }, + { + "id": "session_continuity_learnings_16_masking_a_gate_s_own_escape_hatch_must_cover_every_raw_content_check_in_that_gate_not_just_the_one_the_bug_report_named", + "label": "16. Masking a gate's own escape hatch must cover every raw-`$content` check in that gate, not just the one the bug report named", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "16. masking a gate's own escape hatch must cover every raw-`$content` check in that gate, not just the one the bug report named", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L279" + }, + { + "id": "session_continuity_learnings_17_worktree_isolation_guard_blocks_any_too_complex_command_not_just_git_c_or_compound_git_chains", + "label": "17. Worktree-isolation guard blocks any \"too complex\" command, not just `git -C` or compound git chains", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "17. worktree-isolation guard blocks any \"too complex\" command, not just `git -c` or compound git chains", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L45" + }, + { + "id": "session_continuity_learnings_18_a_subagent_s_done_commit_hash_can_be_a_real_commit_in_the_wrong_repo", + "label": "18. A subagent's \"DONE, commit `<hash>`\" can be a real commit \u2014 in the wrong repo", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "18. a subagent's \"done, commit `<hash>`\" can be a real commit \u2014 in the wrong repo", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L417" + }, + { + "id": "session_continuity_learnings_19_jq_oniguruma_s_m_flag_means_dot_matches_newline_not_pcre_s_s", + "label": "19. jq/Oniguruma's \"m\" flag means dot-matches-newline, not PCRE's \"s\"", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "19. jq/oniguruma's \"m\" flag means dot-matches-newline, not pcre's \"s\"", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L144" + }, + { + "id": "session_continuity_learnings_1_pretooluse_hooks_must_emit_json_to_reach_claude_s_context", + "label": "1. PreToolUse hooks must emit JSON to reach Claude's context", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "1. pretooluse hooks must emit json to reach claude's context", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L367" + }, + { + "id": "session_continuity_learnings_20_a_per_link_or_about_to_become_true_disjunction_fix_for_one_chained_trigger_doesn_t_generalize_to_the_next_link", + "label": "20. A per-link \"OR about to become true\" disjunction fix for one chained trigger doesn't generalize to the next link", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "20. a per-link \"or about to become true\" disjunction fix for one chained trigger doesn't generalize to the next link", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L130" + }, + { + "id": "session_continuity_learnings_21_git_commit_m_cat_eof_eof_triggers_spurious_content_gate_denials_that_a_direct_script_re_test_can_t_reproduce", + "label": "21. `git commit -m \"$(cat <<'EOF' ... EOF)\"` triggers spurious content-gate denials that a direct script re-test can't reproduce", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "21. `git commit -m \"$(cat <<'eof' ... eof)\"` triggers spurious content-gate denials that a direct script re-test can't reproduce", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L238" + }, + { + "id": "session_continuity_learnings_2_awk_changelog_range_collapses_on_single_version_files", + "label": "2. awk CHANGELOG range collapses on single-version files", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "2. awk changelog range collapses on single-version files", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L100" + }, + { + "id": "session_continuity_learnings_3_checklist_style_prose_needs_an_explicit_enumerate_don_t_summarize_rule", + "label": "3. Checklist-style prose needs an explicit \"enumerate, don't summarize\" rule", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "3. checklist-style prose needs an explicit \"enumerate, don't summarize\" rule", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L214" + }, + { + "id": "session_continuity_learnings_4_init_mode_commits_can_leak_placeholder_tokens_when_the_user_skips_ahead", + "label": "4. Init-mode commits can leak `{{PLACEHOLDER}}` tokens when the user skips ahead", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "4. init-mode commits can leak `{{placeholder}}` tokens when the user skips ahead", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L200" + }, + { + "id": "session_continuity_learnings_5_superpowers_style_upstream_skills_hardcode_docs_superpowers_specs_plans_and_silently_re_create_deleted_directories", + "label": "5. Superpowers-style upstream skills hardcode `docs/superpowers/{specs,plans}/` and silently re-create deleted directories", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "5. superpowers-style upstream skills hardcode `docs/superpowers/{specs,plans}/` and silently re-create deleted directories", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L186" + }, + { + "id": "session_continuity_learnings_6_stale_path_references_in_slash_command_bodies_survive_plugin_path_migrations", + "label": "6. Stale path references in slash-command bodies survive plugin path migrations", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "6. stale path references in slash-command bodies survive plugin path migrations", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L172" + }, + { + "id": "session_continuity_learnings_7_a_grep_based_gate_cannot_reliably_scan_a_plan_that_documents_the_gate_s_own_syntax", + "label": "7. A grep-based gate cannot reliably scan a plan that documents the gate's own syntax", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "7. a grep-based gate cannot reliably scan a plan that documents the gate's own syntax", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L353" + }, + { + "id": "session_continuity_learnings_8_git_c_and_compound_commands_blocked_inside_a_worktree_isolated_session", + "label": "8. `git -C` and compound commands blocked inside a worktree-isolated session", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "8. `git -c` and compound commands blocked inside a worktree-isolated session", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L81" + }, + { + "id": "session_continuity_learnings_9_removing_a_hook_s_legacy_path_scope_breaks_hermetic_smoke_fixtures_hardcoded_to_that_path_and_a_release_shipped_before_anyone_re_ran_them", + "label": "9. Removing a hook's legacy-path scope breaks hermetic smoke fixtures hardcoded to that path \u2014 and a release shipped before anyone re-ran them", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "9. removing a hook's legacy-path scope breaks hermetic smoke fixtures hardcoded to that path \u2014 and a release shipped before anyone re-ran them", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L338" + }, + { + "id": "session_continuity_learnings_anti_patterns_we_were_tempted_by_and_rejected", + "label": "Anti-patterns we were tempted by (and rejected)", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "anti-patterns we were tempted by (and rejected)", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L473" + }, + { + "id": "session_continuity_learnings_checklist_for_a_fresh_dev_env_setup", + "label": "Checklist for a fresh dev-env setup", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "checklist for a fresh dev-env setup", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L481" + }, + { + "id": "session_continuity_learnings_claude_code_plugin_mechanics", + "label": "Claude Code plugin mechanics", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "claude code plugin mechanics", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L43" + }, + { + "id": "session_continuity_learnings_git_release_mechanics", + "label": "Git / release mechanics", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "git / release mechanics", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L415" + }, + { + "id": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "label": "Hook scripting (SessionStart / PreToolUse)", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hook scripting (sessionstart / pretooluse)", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L236" + }, + { + "id": "session_continuity_learnings_learnings_session_continuity", + "label": "Learnings \u2014 session-continuity", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "learnings \u2014 session-continuity", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L1" + }, + { + "id": "session_continuity_learnings_security_incidents", + "label": "Security incidents", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "security incidents", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L466" + }, + { + "id": "session_continuity_learnings_slash_command_skill_authoring", + "label": "Slash command skill authoring", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "slash command skill authoring", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L128" + }, + { + "id": "session_continuity_learnings_symptoms_index", + "label": "Symptoms index", + "_origin": "ast", + "community": 2, + "community_name": "Hook scripting (SessionStart / PreToolUse)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "symptoms index", + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design", + "label": "2026-09-02-end-session-step2-rendering-design.md", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-02-end-session-step2-rendering-design.md", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_a_sibling_renderer_not_a_flag_on_the_extractor", + "label": "A sibling renderer, not a flag on the extractor", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "a sibling renderer, not a flag on the extractor", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L71" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "label": "Design", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L54" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "label": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-session step 2 \u2014 rendering and reference relocation (phase 2 design)", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_estimated_effect", + "label": "Estimated effect", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "estimated effect", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L193" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L221" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L204" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_the_correction_that_shapes_the_design", + "label": "The correction that shapes the design", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the correction that shapes the design", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L22" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_the_output_schema_as_it_actually_exists", + "label": "The output schema, as it actually exists", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the output schema, as it actually exists", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L56" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_the_renderer_owns_three_of_four_modes", + "label": "The renderer owns three of four modes", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the renderer owns three of four modes", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L95" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_transcript_resolution_moves_here_too", + "label": "Transcript resolution moves here too", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "transcript resolution moves here too", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L119" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_two_defects_found_while_reading_the_source", + "label": "Two defects found while reading the source", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "two defects found while reading the source", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L37" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_what_step_2_becomes_in_the_prompt", + "label": "What Step 2 becomes in the prompt", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what step 2 becomes in the prompt", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L181" + }, + { + "id": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_where_the_heuristics_documentation_goes", + "label": "Where the heuristics documentation goes", + "_origin": "ast", + "community": 20, + "community_name": "end-session Step 2 \u2014 rendering and reference relocation (Phase 2 design)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "where the heuristics documentation goes", + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L163" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass", + "label": "2026-05-21-end-session-heuristic-pass.md", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-05-21-end-session-heuristic-pass.md", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "label": "End-Session Heuristic Pass Implementation Plan", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-session heuristic pass implementation plan", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L15" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_self_review", + "label": "Self-Review", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L1123" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_10_final_verification_push", + "label": "Task 10: Final verification + push", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 10: final verification + push", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L1051" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_1_document_the_1_outstanding_items_overlay_in_step_1", + "label": "Task 1: Document the \u00a71 outstanding-items overlay in Step 1", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: document the \u00a71 outstanding-items overlay in step 1", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L29" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_2_document_the_5_transcript_resolution_preamble_for_step_2", + "label": "Task 2: Document the \u00a75 transcript-resolution preamble for Step 2", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: document the \u00a75 transcript-resolution preamble for step 2", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L117" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_3_document_the_four_5_heuristics", + "label": "Task 3: Document the four \u00a75 heuristics", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: document the four \u00a75 heuristics", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L252" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_4_update_the_step_2_presentation_block_to_match_heuristic_output", + "label": "Task 4: Update the Step 2 presentation block to match heuristic output", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: update the step 2 presentation block to match heuristic output", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L400" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_5_bump_version_update_changelog", + "label": "Task 5: Bump version + update CHANGELOG", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: bump version + update changelog", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L524" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_6_refresh_primer_for_v0_6_0", + "label": "Task 6: Refresh primer for v0.6.0", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: refresh primer for v0.6.0", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L603" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_7_run_scenario_1_of_the_validation_matrix_clean_repo_no_commits", + "label": "Task 7: Run scenario 1 of the validation matrix (clean repo, no commits)", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: run scenario 1 of the validation matrix (clean repo, no commits)", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L712" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_8_run_scenarios_2_5_of_the_validation_matrix", + "label": "Task 8: Run scenarios 2\u20135 of the validation matrix", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: run scenarios 2\u20135 of the validation matrix", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L793" + }, + { + "id": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_9_dogfood_test_run_session_continuity_end_session_on_this_very_session", + "label": "Task 9: Dogfood test \u2014 run `/session-continuity:end-session` on this very session", + "_origin": "ast", + "community": 21, + "community_name": "End-Session Heuristic Pass Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 9: dogfood test \u2014 run `/session-continuity:end-session` on this very session", + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L929" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action", + "label": "2026-06-15-fire-before-action.md", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-06-15-fire-before-action.md", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L15" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_fire_before_the_action_implementation_plan", + "label": "Fire Before the Action \u2014 Implementation Plan", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fire before the action \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_n_title", + "label": "<N>. <Title>", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "<n>. <title>", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L411" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "label": "Payload contract (reference for all hook tasks)", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "payload contract (reference for all hook tasks)", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L28" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_self_review_notes", + "label": "Self-review notes", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review notes", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L699" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_1_learnings_trigger_parsing_helper_test_first_pure", + "label": "Task 1: LEARNINGS trigger parsing helper (test-first, pure)", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: learnings trigger parsing helper (test-first, pure)", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L43" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_2_smoke_gate_hook", + "label": "Task 2: smoke-gate hook", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: smoke-gate hook", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L192" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_3_register_both_hooks_in_hooks_json", + "label": "Task 3: Register both hooks in hooks.json", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: register both hooks in hooks.json", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L324" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_4_learning_command_optional_trigger_field", + "label": "Task 4: `/learning` command \u2014 optional Trigger field", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: `/learning` command \u2014 optional trigger field", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L388" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_5_template_skill_md_documentation", + "label": "Task 5: Template + SKILL.md documentation", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: template + skill.md documentation", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L439" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_6_version_bump_changelog_readme", + "label": "Task 6: Version bump + CHANGELOG + README", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: version bump + changelog + readme", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L484" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_7_mandatory_smoke_runner", + "label": "Task 7: MANDATORY smoke runner", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: mandatory smoke runner", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L542" + }, + { + "id": "meta_superpowers_plans_2026_06_15_fire_before_action_task_8_backfill_real_triggers_integration_check_on_this_repo", + "label": "Task 8: Backfill real triggers + integration check on this repo", + "_origin": "ast", + "community": 22, + "community_name": "Payload contract (reference for all hook tasks)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: backfill real triggers + integration check on this repo", + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L656" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening", + "label": "2026-09-01-learnings-generation-hardening.md", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-01-learnings-generation-hardening.md", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_7_an_example_heading_inside_a_fence", + "label": "7. an example heading inside a fence", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "7. an example heading inside a fence", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L329" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_findings_this_plan_closes", + "label": "Findings this plan closes", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "findings this plan closes", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L19" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L37" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_learnings_generation_hardening_implementation_plan", + "label": "LEARNINGS generation hardening \u2014 Implementation Plan", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "learnings generation hardening \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_not_in_this_plan", + "label": "Not in this plan", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "not in this plan", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1784" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_self_review", + "label": "Self-review", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1791" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_1_write_gate_for_learnings_index_sh_f1_f2", + "label": "Task 1: Write gate for `learnings-index.sh` (F1, F2)", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: write gate for `learnings-index.sh` (f1, f2)", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L49" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_2_fence_aware_front_matter_safe_awk_passes_f8_f9", + "label": "Task 2: Fence-aware, front-matter-safe awk passes (F8, F9)", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: fence-aware, front-matter-safe awk passes (f8, f9)", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L297" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_3_failure_taxonomy_and_portability_for_candidate_extract_sh_f2_f6_f7", + "label": "Task 3: Failure taxonomy and portability for `candidate-extract.sh` (F2, F6, F7)", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: failure taxonomy and portability for `candidate-extract.sh` (f2, f6, f7)", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L527" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_4_retune_the_heuristics_against_real_transcripts_f3_f4_f5", + "label": "Task 4: Retune the heuristics against real transcripts (F3, F4, F5)", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: retune the heuristics against real transcripts (f3, f4, f5)", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L752" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_5_replay_harness_for_real_transcripts_f3_f4_f11", + "label": "Task 5: Replay harness for real transcripts (F3, F4, F11)", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: replay harness for real transcripts (f3, f4, f11)", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1319" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_6_rewire_the_command_prose_f10_and_the_new_mode_error", + "label": "Task 6: Rewire the command prose (F10, and the new `mode:\"error\"`)", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: rewire the command prose (f10, and the new `mode:\"error\"`)", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1455" + }, + { + "id": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_7_run_the_ritual_end_to_end_and_release_f11", + "label": "Task 7: Run the ritual end to end and release (F11)", + "_origin": "ast", + "community": 23, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: run the ritual end to end and release (f11)", + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1698" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template", + "label": "2026-09-09-primer-thin-hard-template.md", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-09-primer-thin-hard-template.md", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "label": "File map", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file map", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L32" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_self_review_notes_post_caveman_review", + "label": "Self-review notes (post caveman-review)", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review notes (post caveman-review)", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L448" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_spec_coverage_checklist", + "label": "Spec coverage checklist", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "spec coverage checklist", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L425" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_1_peer_probes_sh_smoke", + "label": "Task 1: `peer-probes.sh` + smoke", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `peer-probes.sh` + smoke", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L56" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_2_primer_validate_sh_smoke", + "label": "Task 2: `primer-validate.sh` + smoke", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `primer-validate.sh` + smoke", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L137" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_3_primer_freshness_sh_smoke", + "label": "Task 3: `primer-freshness.sh` + smoke", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: `primer-freshness.sh` + smoke", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L193" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_4_thin_template_copy_churn_templates_only", + "label": "Task 4: Thin template + copy churn (templates only)", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: thin template + copy churn (templates only)", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L232" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_5_wire_sessionstart", + "label": "Task 5: Wire SessionStart", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: wire sessionstart", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L258" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_6_doctor_command_wiring", + "label": "Task 6: Doctor command wiring", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: doctor command wiring", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L301" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_7_primer_end_session_pre_commit_prose", + "label": "Task 7: Primer + end-session + pre-commit prose", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: primer + end-session + pre-commit prose", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L340" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_8_dogfood_privacy_copy_version_bump", + "label": "Task 8: Dogfood + privacy copy + version bump", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: dogfood + privacy copy + version bump", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L376" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_thin_hard_template_session_primer_implementation_plan", + "label": "Thin hard-template SESSION_PRIMER Implementation Plan", + "_origin": "ast", + "community": 24, + "community_name": "File map", + "file_type": "document", + "node_kind": "heading", + "norm_label": "thin hard-template session_primer implementation plan", + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design", + "label": "2026-06-17-proven-gate-design.md", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-06-17-proven-gate-design.md", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_detection_rule", + "label": "Detection rule", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "detection rule", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L44" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_escape_hatch_explicit_skip_with_reason", + "label": "Escape hatch (explicit skip-with-reason)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "escape hatch (explicit skip-with-reason)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L70" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_mechanics_reuse_smoke_gate_sh_exactly", + "label": "Mechanics (reuse smoke-gate.sh exactly)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "mechanics (reuse smoke-gate.sh exactly)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L85" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_out_of_scope_other_change_the_odds_deliverables_sequenced_after_this", + "label": "Out of scope (other change-the-odds deliverables, sequenced after this)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope (other change-the-odds deliverables, sequenced after this)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L193" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "label": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_scope_decided", + "label": "Scope (decided)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scope (decided)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L33" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_self_reference_trap_learnings_7_1_read_before_implementing", + "label": "Self-reference trap (LEARNINGS #7 + #1 \u2014 read before implementing)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-reference trap (learnings #7 + #1 \u2014 read before implementing)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L151" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_success_criterion_the_invariant", + "label": "Success criterion (the invariant)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "success criterion (the invariant)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L184" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_testing_hermetic_no_containers", + "label": "Testing (hermetic, no containers)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing (hermetic, no containers)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L129" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_the_problem_this_gate_exists_to_stop", + "label": "The problem this gate exists to stop", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the problem this gate exists to stop", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L12" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_versioning_ship", + "label": "Versioning / ship", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "versioning / ship", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L174" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_what_it_does_one_sentence", + "label": "What it does (one sentence)", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what it does (one sentence)", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L26" + }, + { + "id": "meta_superpowers_specs_2026_06_17_proven_gate_design_wiring", + "label": "Wiring", + "_origin": "ast", + "community": 25, + "community_name": "Proven-gate \u2014 make \"proven\" a checkable claim, not a feeling", + "file_type": "document", + "node_kind": "heading", + "norm_label": "wiring", + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L115" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates", + "label": "2026-08-27-commit-time-content-gates.md", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-27-commit-time-content-gates.md", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_commit_time_content_gates_implementation_plan", + "label": "Commit-Time Content Gates Implementation Plan", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "commit-time content gates implementation plan", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_self_review", + "label": "Self-Review", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L868" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_1_shared_gate_library_test_harness", + "label": "Task 1: Shared gate library + test harness", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: shared gate library + test harness", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L27" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_2_proven_gate_commit_time_reference_implementation", + "label": "Task 2: proven-gate \u2192 commit-time (reference implementation)", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: proven-gate \u2192 commit-time (reference implementation)", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L242" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_3_smoke_gate_commit_time", + "label": "Task 3: smoke-gate \u2192 commit-time", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: smoke-gate \u2192 commit-time", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L382" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_4_evidence_gate_commit_time", + "label": "Task 4: evidence-gate \u2192 commit-time", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: evidence-gate \u2192 commit-time", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L466" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_5_backend_parity_gate_commit_time", + "label": "Task 5: backend-parity-gate \u2192 commit-time", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: backend-parity-gate \u2192 commit-time", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L539" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_6_occurrence_gate_commit_time", + "label": "Task 6: occurrence-gate \u2192 commit-time", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: occurrence-gate \u2192 commit-time", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L605" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_7_flaky_gate_dual_commit_message_staged_learnings", + "label": "Task 7: flaky-gate \u2192 dual (commit message + staged LEARNINGS)", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: flaky-gate \u2192 dual (commit message + staged learnings)", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L679" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_8_rewire_hooks_json_contract_runner_full_suite", + "label": "Task 8: Rewire hooks.json + contract runner + full suite", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: rewire hooks.json + contract runner + full suite", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L754" + }, + { + "id": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_9_docs_version_learnings_primer", + "label": "Task 9: Docs, version, LEARNINGS, primer", + "_origin": "ast", + "community": 26, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 9: docs, version, learnings, primer", + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L831" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file", + "label": "2026-08-30-outstanding-items-file.md", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-30-outstanding-items-file.md", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "label": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "standalone outstanding_items.md implementation plan", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_10_end_to_end_scratch_validation", + "label": "Task 10: End-to-end scratch validation", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 10: end-to-end scratch validation", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L827" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_1_new_template_retire_the_old_placeholder", + "label": "Task 1: New template, retire the old placeholder", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: new template, retire the old placeholder", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L25" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_2_repoint_session_start_sh", + "label": "Task 2: Repoint `session-start.sh`", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: repoint `session-start.sh`", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L118" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_3_primer_md_init_mode_seed_the_fourth_file", + "label": "Task 3: `primer.md` Init mode \u2014 seed the fourth file", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: `primer.md` init mode \u2014 seed the fourth file", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L255" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_4_primer_md_split_mode_extend_with_the_new_detector", + "label": "Task 4: `primer.md` Split mode \u2014 extend with the new detector", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: `primer.md` split mode \u2014 extend with the new detector", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L326" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_5_primer_md_refresh_flow_retarget_to_the_new_file", + "label": "Task 5: `primer.md` Refresh flow \u2014 retarget to the new file", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: `primer.md` refresh flow \u2014 retarget to the new file", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L406" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_6_end_session_md_retarget_verification_add_the_migration_nudge", + "label": "Task 6: `end-session.md` \u2014 retarget verification, add the migration nudge", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: `end-session.md` \u2014 retarget verification, add the migration nudge", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L476" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_7_skill_md_document_the_fourth_file", + "label": "Task 7: `SKILL.md` \u2014 document the fourth file", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: `skill.md` \u2014 document the fourth file", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L572" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_8_claude_md_snippet_md_and_readme_md", + "label": "Task 8: `CLAUDE_MD_SNIPPET.md` and `README.md`", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: `claude_md_snippet.md` and `readme.md`", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L634" + }, + { + "id": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_9_migrate_this_repo_s_own_primer_dogfood", + "label": "Task 9: Migrate this repo's own primer (dogfood)", + "_origin": "ast", + "community": 27, + "community_name": "Standalone OUTSTANDING_ITEMS.md Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 9: migrate this repo's own primer (dogfood)", + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L723" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design", + "label": "2026-08-13-primer-volatile-stable-split-design.md", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-13-primer-volatile-stable-split-design.md", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_commands_end_session_md", + "label": "`commands/end-session.md`", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`commands/end-session.md`", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L88" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_commands_learning_md", + "label": "`commands/learning.md`", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`commands/learning.md`", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L105" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "label": "Decision", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "decision", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L30" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_design_split_session_primer_md_into_volatile_stable_files", + "label": "Design \u2014 split SESSION_PRIMER.md into volatile + stable files", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design \u2014 split session_primer.md into volatile + stable files", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_hooks", + "label": "Hooks", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hooks", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L77" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_init_mode", + "label": "Init mode", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "init mode", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L68" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_migration", + "label": "Migration", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "migration", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L46" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L130" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L6" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_skills_session_continuity_skill_md", + "label": "`skills/session-continuity/SKILL.md`", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`skills/session-continuity/skill.md`", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L109" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L139" + }, + { + "id": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_this_repo_dogfood", + "label": "This repo (dogfood)", + "_origin": "ast", + "community": 28, + "community_name": "Decision", + "file_type": "document", + "node_kind": "heading", + "norm_label": "this repo (dogfood)", + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L123" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design", + "label": "2026-08-31-backlog-roadmap-help-design.md", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-31-backlog-roadmap-help-design.md", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_backlog_md_rename_details", + "label": "BACKLOG.md \u2014 rename details", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "backlog.md \u2014 rename details", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L87" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "label": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design: backlog.md rename, roadmap.md, and /session-continuity:help", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_file_inventory_every_touchpoint", + "label": "File inventory (every touchpoint)", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file inventory (every touchpoint)", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L38" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_goals", + "label": "Goals", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goals", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L16" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_migration_primer_md_step_3c_new", + "label": "Migration \u2014 primer.md Step 3c (new)", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "migration \u2014 primer.md step 3c (new)", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L128" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L31" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_open_questions", + "label": "Open questions", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "open questions", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L228" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L6" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_roadmap_md_new_stub_template", + "label": "ROADMAP.md \u2014 new stub template", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "roadmap.md \u2014 new stub template", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L97" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_rollout", + "label": "Rollout", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "rollout", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L214" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_session_continuity_help_command_design", + "label": "/session-continuity:help \u2014 command design", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:help \u2014 command design", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L179" + }, + { + "id": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_session_start_sh_new_elif_branch", + "label": "session-start.sh \u2014 new elif branch", + "_origin": "ast", + "community": 29, + "community_name": "Design: BACKLOG.md rename, ROADMAP.md, and /session-continuity:help", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session-start.sh \u2014 new elif branch", + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L171" + }, + { + "id": "changelog", + "label": "CHANGELOG.md", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "page", + "norm_label": "changelog.md", + "source_file": "CHANGELOG.md", + "source_location": "L1" + }, + { + "id": "changelog_0_12_0_2026_07_30", + "label": "[0.12.0] \u2014 2026-07-30", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.12.0] \u2014 2026-07-30", + "source_file": "CHANGELOG.md", + "source_location": "L570" + }, + { + "id": "changelog_0_12_1_2026_08_06", + "label": "[0.12.1] \u2014 2026-08-06", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.12.1] \u2014 2026-08-06", + "source_file": "CHANGELOG.md", + "source_location": "L548" + }, + { + "id": "changelog_0_14_2_2026_08_14", + "label": "[0.14.2] \u2014 2026-08-14", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.14.2] \u2014 2026-08-14", + "source_file": "CHANGELOG.md", + "source_location": "L403" + }, + { + "id": "changelog_0_14_3_2026_08_14", + "label": "[0.14.3] \u2014 2026-08-14", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.14.3] \u2014 2026-08-14", + "source_file": "CHANGELOG.md", + "source_location": "L389" + }, + { + "id": "changelog_0_14_4_2026_08_15", + "label": "[0.14.4] \u2014 2026-08-15", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.14.4] \u2014 2026-08-15", + "source_file": "CHANGELOG.md", + "source_location": "L350" + }, + { + "id": "changelog_0_1_0_2026_04_26", + "label": "[0.1.0] \u2014 2026-04-26", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.1.0] \u2014 2026-04-26", + "source_file": "CHANGELOG.md", + "source_location": "L740" + }, + { + "id": "changelog_0_24_0_2026_09_01", + "label": "[0.24.0] \u2014 2026-09-01", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.24.0] \u2014 2026-09-01", + "source_file": "CHANGELOG.md", + "source_location": "L126" + }, + { + "id": "changelog_0_25_1_2026_09_02", + "label": "[0.25.1] \u2014 2026-09-02", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.25.1] \u2014 2026-09-02", + "source_file": "CHANGELOG.md", + "source_location": "L106" + }, + { + "id": "changelog_0_25_2_2026_09_02", + "label": "[0.25.2] \u2014 2026-09-02", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.25.2] \u2014 2026-09-02", + "source_file": "CHANGELOG.md", + "source_location": "L100" + }, + { + "id": "changelog_0_26_0_2026_09_02", + "label": "[0.26.0] \u2014 2026-09-02", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.26.0] \u2014 2026-09-02", + "source_file": "CHANGELOG.md", + "source_location": "L93" + }, + { + "id": "changelog_0_27_1_2026_09_04", + "label": "[0.27.1] \u2014 2026-09-04", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.27.1] \u2014 2026-09-04", + "source_file": "CHANGELOG.md", + "source_location": "L82" + }, + { + "id": "changelog_0_31_0_2026_09_08", + "label": "[0.31.0] \u2014 2026-09-08", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.31.0] \u2014 2026-09-08", + "source_file": "CHANGELOG.md", + "source_location": "L48" + }, + { + "id": "changelog_0_33_0_2026_09_09", + "label": "[0.33.0] \u2014 2026-09-09", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.33.0] \u2014 2026-09-09", + "source_file": "CHANGELOG.md", + "source_location": "L38" + }, + { + "id": "changelog_added_572", + "label": "Added", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L572" + }, + { + "id": "changelog_added_95", + "label": "Added", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L95" + }, + { + "id": "changelog_changed_128", + "label": "Changed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L128" + }, + { + "id": "changelog_changed_40", + "label": "Changed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L40" + }, + { + "id": "changelog_changed_50", + "label": "Changed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L50" + }, + { + "id": "changelog_changelog", + "label": "Changelog", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changelog", + "source_file": "CHANGELOG.md", + "source_location": "L1" + }, + { + "id": "changelog_compatibility", + "label": "Compatibility", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L565" + }, + { + "id": "changelog_fixed_102", + "label": "Fixed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L102" + }, + { + "id": "changelog_fixed_108", + "label": "Fixed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L108" + }, + { + "id": "changelog_fixed_352", + "label": "Fixed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L352" + }, + { + "id": "changelog_fixed_391", + "label": "Fixed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L391" + }, + { + "id": "changelog_fixed_405", + "label": "Fixed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L405" + }, + { + "id": "changelog_fixed_550", + "label": "Fixed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L550" + }, + { + "id": "changelog_fixed_84", + "label": "Fixed", + "_origin": "ast", + "community": 3, + "community_name": "Changelog", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L84" + }, + { + "id": "commands_primer", + "label": "primer.md", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "frontmatter": { + "description": "Init, refresh, or check .session-continuity/SESSION_PRIMER.md \u2014 dispatches based on current state." + }, + "node_kind": "page", + "norm_label": "primer.md", + "source_file": "commands/primer.md", + "source_location": "L1" + }, + { + "id": "commands_primer_notes", + "label": "Notes", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "notes", + "source_file": "commands/primer.md", + "source_location": "L432" + }, + { + "id": "commands_primer_session_continuity_primer", + "label": "/session-continuity:primer", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:primer", + "source_file": "commands/primer.md", + "source_location": "L5" + }, + { + "id": "commands_primer_step_1_detect_state", + "label": "Step 1 \u2014 Detect state", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 \u2014 detect state", + "source_file": "commands/primer.md", + "source_location": "L11" + }, + { + "id": "commands_primer_step_2_init_mode", + "label": "Step 2 \u2014 Init mode", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 \u2014 init mode", + "source_file": "commands/primer.md", + "source_location": "L76" + }, + { + "id": "commands_primer_step_3_split_mode", + "label": "Step 3 \u2014 Split mode", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3 \u2014 split mode", + "source_file": "commands/primer.md", + "source_location": "L172" + }, + { + "id": "commands_primer_step_3b_outstanding_items_split", + "label": "Step 3b \u2014 Outstanding-items split", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3b \u2014 outstanding-items split", + "source_file": "commands/primer.md", + "source_location": "L213" + }, + { + "id": "commands_primer_step_3c_backlog_rename_migration", + "label": "Step 3c \u2014 Backlog rename migration", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3c \u2014 backlog rename migration", + "source_file": "commands/primer.md", + "source_location": "L247" + }, + { + "id": "commands_primer_step_3d_backlog_md_github_issues", + "label": "Step 3d \u2014 BACKLOG.md \u2192 GitHub Issues", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3d \u2014 backlog.md \u2192 github issues", + "source_file": "commands/primer.md", + "source_location": "L288" + }, + { + "id": "commands_primer_step_4_refresh_mode", + "label": "Step 4 \u2014 Refresh mode", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 4 \u2014 refresh mode", + "source_file": "commands/primer.md", + "source_location": "L309" + }, + { + "id": "commands_primer_step_4b_slim_migrate_mode", + "label": "Step 4b \u2014 Slim-migrate mode", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 4b \u2014 slim-migrate mode", + "source_file": "commands/primer.md", + "source_location": "L356" + }, + { + "id": "commands_primer_step_5_check_mode", + "label": "Step 5 \u2014 Check mode", + "_origin": "ast", + "community": 30, + "community_name": "/session-continuity:primer", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 5 \u2014 check mode", + "source_file": "commands/primer.md", + "source_location": "L387" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix", + "label": "2026-08-12-hook-json-escaping-fix.md", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-12-hook-json-escaping-fix.md", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_deferred_with_reasons", + "label": "Deferred, with reasons", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "deferred, with reasons", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L417" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_end_state_invariant", + "label": "End-state invariant", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-state invariant", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L54" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_global_constraints", + "label": "Global constraints", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L60" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "label": "Hook JSON-escaping fix \u2014 implementation plan", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hook json-escaping fix \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_self_review", + "label": "Self-review", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L422" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_1_the_contract_runner_write_it_first_watch_it_fail", + "label": "Task 1: The contract runner (write it first, watch it fail)", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: the contract runner (write it first, watch it fail)", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L73" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_2_escape_the_reason_at_the_point_of_emission", + "label": "Task 2: Escape the reason at the point of emission", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: escape the reason at the point of emission", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L199" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_3_record_why_the_tests_missed_it", + "label": "Task 3: Record why the tests missed it", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: record why the tests missed it", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L305" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_4_release_0_12_2", + "label": "Task 4: Release 0.12.2", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: release 0.12.2", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L349" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_the_defect", + "label": "The defect", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the defect", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L21" + }, + { + "id": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_why_the_runners_are_green", + "label": "Why the runners are green", + "_origin": "ast", + "community": 31, + "community_name": "Hook JSON-escaping fix \u2014 implementation plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "why the runners are green", + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L44" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution", + "label": "2026-09-01-end-session-step2-cost-attribution.md", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-01-end-session-step2-cost-attribution.md", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_end_session_step_2_cost_attribution_implementation_plan", + "label": "End-session Step 2 cost attribution \u2014 Implementation Plan", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-session step 2 cost attribution \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_1_shared_version_skew_guard", + "label": "Task 1: Shared version-skew guard", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: shared version-skew guard", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L24" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_2_candidate_extraction_script_change_1", + "label": "Task 2: Candidate-extraction script (Change 1)", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: candidate-extraction script (change 1)", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L151" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_3_wire_commands_end_session_md_step_2_to_the_script", + "label": "Task 3: Wire `commands/end-session.md` Step 2 to the script", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: wire `commands/end-session.md` step 2 to the script", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L556" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_4_agent_active_time_script_change_2", + "label": "Task 4: Agent-active-time script (Change 2)", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: agent-active-time script (change 2)", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L625" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_5_wire_commands_end_session_md_step_4_to_agent_active_sh_retire_step_4_compute_only", + "label": "Task 5: Wire `commands/end-session.md` Step 4 to `agent-active.sh`, retire `step-4-compute-only`", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: wire `commands/end-session.md` step 4 to `agent-active.sh`, retire `step-4-compute-only`", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L804" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_6_learnings_md_derivations_script_change_3", + "label": "Task 6: LEARNINGS.md derivations script (Change 3)", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: learnings.md derivations script (change 3)", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L861" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_7_wire_commands_learning_md_steps_4_and_6_to_the_script", + "label": "Task 7: Wire `commands/learning.md` Steps 4 and 6 to the script", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: wire `commands/learning.md` steps 4 and 6 to the script", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1183" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_8_wire_commands_end_session_md_s_capture_flow_to_call_the_index_script_directly", + "label": "Task 8: Wire `commands/end-session.md`'s capture flow to call the index script directly", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: wire `commands/end-session.md`'s capture flow to call the index script directly", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1259" + }, + { + "id": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_9_end_to_end_validation_changelog_spec_backlog_cross_references", + "label": "Task 9: End-to-end validation, CHANGELOG, spec/backlog cross-references", + "_origin": "ast", + "community": 32, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 9: end-to-end validation, changelog, spec/backlog cross-references", + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1304" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects", + "label": "2026-09-02-fresh-install-count-defects.md", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-02-fresh-install-count-defects.md", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_fresh_install_count_defects_implementation_plan_phase_0", + "label": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fresh-install count defects \u2014 implementation plan (phase 0)", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L75" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L237" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_smoke_coverage_mandatory", + "label": "Smoke coverage (MANDATORY)", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "smoke coverage (mandatory)", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L229" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_1_count_entries_sh", + "label": "Task 1: `count-entries.sh`", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `count-entries.sh`", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L89" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_2_rewrite_session_start_sh_s_two_call_sites", + "label": "Task 2: Rewrite `session-start.sh`'s two call sites", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: rewrite `session-start.sh`'s two call sites", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L127" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_3_rewrite_primer_md_check_mode", + "label": "Task 3: Rewrite `primer.md` check mode", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: rewrite `primer.md` check mode", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L162" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_4_fix_the_two_templates", + "label": "Task 4: Fix the two templates", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: fix the two templates", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L183" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_5_release_bookkeeping", + "label": "Task 5: Release bookkeeping", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: release bookkeeping", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L204" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_the_two_reproductions", + "label": "The two reproductions", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the two reproductions", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L32" + }, + { + "id": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_why_a_shared_helper_rather_than_editing_the_templates_alone", + "label": "Why a shared helper rather than editing the templates alone", + "_origin": "ast", + "community": 33, + "community_name": "Fresh-install count defects \u2014 Implementation Plan (Phase 0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "why a shared helper rather than editing the templates alone", + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L57" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification", + "label": "validation/2026-07-30-outstanding-items-verification.md", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "page", + "norm_label": "validation/2026-07-30-outstanding-items-verification.md", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_acceptance_gate", + "label": "Acceptance gate", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "acceptance gate", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L119" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_in_repo_manual_check_real_grep_count", + "label": "In-repo manual check \u2014 real grep count", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "in-repo manual check \u2014 real grep count", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L109" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_1_case_a_drift_detected_appears_done_item_routes_to_the_combined_prompt_as_a_close_candidate_with_cited_evidence", + "label": "Scenario 1 \u2014 Case A: drift detected, appears-DONE item routes to the combined prompt as a close-candidate with cited evidence", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 1 \u2014 case a: drift detected, appears-done item routes to the combined prompt as a close-candidate with cited evidence", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_2_case_b_drift_clean_verification_runs_no_prompt_verdict_held_for_step_3_only", + "label": "Scenario 2 \u2014 Case B: drift-clean, verification runs, no prompt, verdict held for Step 3 only", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 2 \u2014 case b: drift-clean, verification runs, no prompt, verdict held for step 3 only", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L25" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_3_case_c_user_closes_an_appears_done_item_at_the_prompt_then_step_3_re_derives_item_absent_marker_checkmark", + "label": "Scenario 3 \u2014 Case C: user closes an appears-DONE item at the prompt, then Step 3 re-derives, item absent, marker checkmark", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 3 \u2014 case c: user closes an appears-done item at the prompt, then step 3 re-derives, item absent, marker checkmark", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L37" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_4_case_d_drift_clean_stale_item_step_3_reports_it_marker_warning_no_deletion", + "label": "Scenario 4 \u2014 Case D: drift-clean stale item, Step 3 reports it, marker warning, no deletion", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 4 \u2014 case d: drift-clean stale item, step 3 reports it, marker warning, no deletion", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L49" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_5_never_auto_close_invariant_appears_done_item_no_changes_reply_item_still_present_in_primer_afterward_step_3_still_warning_appears_done", + "label": "Scenario 5 \u2014 never-auto-close invariant: appears-DONE item + \"no changes\" reply, item STILL present in primer afterward, Step 3 still warning appears-DONE", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 5 \u2014 never-auto-close invariant: appears-done item + \"no changes\" reply, item still present in primer afterward, step 3 still warning appears-done", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L61" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_6_non_code_item_marketplace_submission_verdict_manual_not_auto_verifiable_never_asserted", + "label": "Scenario 6 \u2014 non-code item (marketplace submission): verdict manual \u2014 not auto-verifiable, never asserted", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 6 \u2014 non-code item (marketplace submission): verdict manual \u2014 not auto-verifiable, never asserted", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L73" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_7_ambiguous_grep_match_inside_a_comment_manual_not_appears_done_bias_rule", + "label": "Scenario 7 \u2014 ambiguous grep (match inside a comment): manual, not appears-DONE (bias rule)", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 7 \u2014 ambiguous grep (match inside a comment): manual, not appears-done (bias rule)", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L85" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_8_no_outstanding_items_heading_verification_skipped_row_reads_none_tracked", + "label": "Scenario 8 \u2014 no Outstanding items heading: verification skipped, row reads \"none tracked\"", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 8 \u2014 no outstanding items heading: verification skipped, row reads \"none tracked\"", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L97" + }, + { + "id": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "label": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "_origin": "ast", + "community": 34, + "community_name": "Validation log \u2014 outstanding-items verification (v0.12.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "validation log \u2014 outstanding-items verification (v0.12.0)", + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L1" + }, + { + "id": "session_continuity_project_context", + "label": ".session-continuity/PROJECT_CONTEXT.md", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "page", + "norm_label": ".session-continuity/project_context.md", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L1" + }, + { + "id": "session_continuity_project_context_end_to_end_check_real_integration", + "label": "End-to-end check (real integration)", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-to-end check (real integration)", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L55" + }, + { + "id": "session_continuity_project_context_ground_rules_how_to_work_here", + "label": "Ground rules (how to work here)", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "ground rules (how to work here)", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L8" + }, + { + "id": "session_continuity_project_context_if_you_get_stuck", + "label": "If you get stuck", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "if you get stuck", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L85" + }, + { + "id": "session_continuity_project_context_maintenance_your_responsibility", + "label": "Maintenance (your responsibility)", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "maintenance (your responsibility)", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L95" + }, + { + "id": "session_continuity_project_context_project_context_session_continuity", + "label": "Project Context \u2014 session-continuity", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "project context \u2014 session-continuity", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L1" + }, + { + "id": "session_continuity_project_context_repo_layout", + "label": "Repo layout", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "repo layout", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L15" + }, + { + "id": "session_continuity_project_context_test_expectations_these_must_stay_green", + "label": "Test expectations \u2014 these must stay green", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "test expectations \u2014 these must stay green", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L51" + }, + { + "id": "session_continuity_project_context_the_packages_modules", + "label": "The packages / modules", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the packages / modules", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L41" + }, + { + "id": "session_continuity_project_context_where_to_look_for_what", + "label": "Where to look for what", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "where to look for what", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L74" + }, + { + "id": "session_continuity_project_context_workflow_conventions", + "label": "Workflow conventions", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "workflow conventions", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L66" + }, + { + "id": "session_continuity_project_context_working_directory", + "label": "Working directory", + "_origin": "ast", + "community": 35, + "community_name": "Project Context \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "working directory", + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L33" + }, + { + "id": "commands_learning", + "label": "learning.md", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "frontmatter": { + "description": "Append a new entry to .session-continuity/LEARNINGS.md interactively. Takes next N+1 number, inserts at top of chosen section." + }, + "node_kind": "page", + "norm_label": "learning.md", + "source_file": "commands/learning.md", + "source_location": "L1" + }, + { + "id": "commands_learning_notes", + "label": "Notes", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "notes", + "source_file": "commands/learning.md", + "source_location": "L156" + }, + { + "id": "commands_learning_session_continuity_learning_arguments", + "label": "/session-continuity:learning $ARGUMENTS", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:learning $arguments", + "source_file": "commands/learning.md", + "source_location": "L5" + }, + { + "id": "commands_learning_step_1_preflight", + "label": "Step 1 \u2014 Preflight", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 \u2014 preflight", + "source_file": "commands/learning.md", + "source_location": "L13" + }, + { + "id": "commands_learning_step_2_gather_the_recipe", + "label": "Step 2 \u2014 Gather the recipe", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 \u2014 gather the recipe", + "source_file": "commands/learning.md", + "source_location": "L22" + }, + { + "id": "commands_learning_step_3_choose_section", + "label": "Step 3 \u2014 Choose section", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3 \u2014 choose section", + "source_file": "commands/learning.md", + "source_location": "L36" + }, + { + "id": "commands_learning_step_4_compute_next_number_with_uniqueness_guard", + "label": "Step 4 \u2014 Compute next number (with uniqueness guard)", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 4 \u2014 compute next number (with uniqueness guard)", + "source_file": "commands/learning.md", + "source_location": "L52" + }, + { + "id": "commands_learning_step_5_insert_at_top_of_chosen_section", + "label": "Step 5 \u2014 Insert at top of chosen section", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 5 \u2014 insert at top of chosen section", + "source_file": "commands/learning.md", + "source_location": "L84" + }, + { + "id": "commands_learning_step_6_regenerate_the_symptoms_index", + "label": "Step 6 \u2014 Regenerate the Symptoms index", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 6 \u2014 regenerate the symptoms index", + "source_file": "commands/learning.md", + "source_location": "L114" + }, + { + "id": "commands_learning_step_7_bump_the_footer", + "label": "Step 7 \u2014 Bump the footer", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 7 \u2014 bump the footer", + "source_file": "commands/learning.md", + "source_location": "L138" + }, + { + "id": "commands_learning_step_8_stage", + "label": "Step 8 \u2014 Stage", + "_origin": "ast", + "community": 36, + "community_name": "/session-continuity:learning $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 8 \u2014 stage", + "source_file": "commands/learning.md", + "source_location": "L148" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging", + "label": "plans/2026-08-17-performance-logging.md", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "plans/2026-08-17-performance-logging.md", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L41" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_per_repo_performance_logging_implementation_plan", + "label": "Per-repo performance logging \u2014 Implementation Plan", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "per-repo performance logging \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_self_review_notes", + "label": "Self-Review Notes", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review notes", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1329" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_task_1_shared_writer_hooks_lib_perf_log_sh", + "label": "Task 1: Shared writer \u2014 `hooks/lib/perf-log.sh`", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: shared writer \u2014 `hooks/lib/perf-log.sh`", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L72" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_task_2_hook_timing_wrapper_hooks_lib_perf_wrap_sh", + "label": "Task 2: Hook timing wrapper \u2014 `hooks/lib/perf-wrap.sh`", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: hook timing wrapper \u2014 `hooks/lib/perf-wrap.sh`", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L273" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_task_3_wire_hooks_hooks_json_through_the_wrapper", + "label": "Task 3: Wire `hooks/hooks.json` through the wrapper", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: wire `hooks/hooks.json` through the wrapper", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L458" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_task_4_instrument_commands_primer_md", + "label": "Task 4: Instrument `commands/primer.md`", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: instrument `commands/primer.md`", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L644" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_task_5_instrument_commands_end_session_md", + "label": "Task 5: Instrument `commands/end-session.md`", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: instrument `commands/end-session.md`", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L931" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_task_6_version_bump_changelog_readme_note", + "label": "Task 6: Version bump, CHANGELOG, README note", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: version bump, changelog, readme note", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1193" + }, + { + "id": "meta_superpowers_plans_2026_08_17_performance_logging_task_7_end_to_end_validation_log", + "label": "Task 7: End-to-end validation log", + "_origin": "ast", + "community": 37, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: end-to-end validation log", + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1281" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands", + "label": "2026-09-02-zero-turn-read-only-commands.md", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-02-zero-turn-read-only-commands.md", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_deliberately_out_of_scope", + "label": "Deliberately out of scope", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "deliberately out of scope", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L400" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L67" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_status_tasks_2_6_are_provisional_pending_task_1", + "label": "Status: Tasks 2-6 are provisional pending Task 1", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "status: tasks 2-6 are provisional pending task 1", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L60" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_1_measure_the_interception_surface_gate", + "label": "Task 1: Measure the interception surface (GATE)", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: measure the interception surface (gate)", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L119" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_2_renderer_layer", + "label": "Task 2: Renderer layer", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: renderer layer", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L186" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_3_interception_layer", + "label": "Task 3: Interception layer", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: interception layer", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L244" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_4_command_stubs_with_working_fallback_bodies", + "label": "Task 4: Command stubs with working fallback bodies", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: command stubs with working fallback bodies", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L302" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_5_interception_smoke_test_mandatory", + "label": "Task 5: Interception smoke test (MANDATORY)", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: interception smoke test (mandatory)", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L337" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_6_docs_changelog_version", + "label": "Task 6: Docs, changelog, version", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: docs, changelog, version", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L365" + }, + { + "id": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_zero_turn_read_only_commands_implementation_plan_phase_1", + "label": "Zero-turn read-only commands \u2014 Implementation Plan (Phase 1)", + "_origin": "ast", + "community": 38, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "zero-turn read-only commands \u2014 implementation plan (phase 1)", + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design", + "label": "2026-09-09-test-count-rerun-design.md", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-09-test-count-rerun-design.md", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_architecture", + "label": "Architecture", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "architecture", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L47" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_context", + "label": "Context", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "context", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L5" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "label": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design \u2014 `test-count-rerun.sh`/`.jq` (determinism phase 6, sub-project b)", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_error_handling", + "label": "Error handling", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "error handling", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L150" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L193" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_output_contract", + "label": "Output contract", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "output contract", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L84" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L19" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_recorded_count_format_existing_unchanged", + "label": "Recorded-count format (existing, unchanged)", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "recorded-count format (existing, unchanged)", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L31" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_rollout", + "label": "Rollout", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "rollout", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L184" + }, + { + "id": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 39, + "community_name": "Design \u2014 `test-count-rerun.sh`/`.jq` (Determinism Phase 6, sub-project B)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L161" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release", + "label": "2026-04-27-session-continuity-v0.2-public-release.md", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-04-27-session-continuity-v0.2-public-release.md", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design", + "label": "2026-04-27-session-continuity-v0.2-public-release-design.md", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_acceptance_criteria", + "label": "Acceptance criteria", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "acceptance criteria", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L318" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_changelog_md", + "label": "`CHANGELOG.md`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`changelog.md`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L232" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands", + "label": "Commands", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "commands", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L83" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands_learning_md_session_continuity_learning", + "label": "`commands/learning.md` \u2192 `/session-continuity:learning`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`commands/learning.md` \u2192 `/session-continuity:learning`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L95" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands_primer_md_session_continuity_primer", + "label": "`commands/primer.md` \u2192 `/session-continuity:primer`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`commands/primer.md` \u2192 `/session-continuity:primer`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L87" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "label": "Component designs", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "component designs", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L50" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_distribution_plan", + "label": "Distribution plan", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "distribution plan", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L276" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_github_workflows_release_yml", + "label": "`.github/workflows/release.yml`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`.github/workflows/release.yml`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L187" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_gitignore", + "label": "`.gitignore`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`.gitignore`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L265" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_goal", + "label": "Goal", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goal", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L5" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks", + "label": "Hooks", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hooks", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L105" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks_pre_commit_check_sh", + "label": "`hooks/pre-commit-check.sh`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/pre-commit-check.sh`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L143" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks_session_start_sh", + "label": "`hooks/session-start.sh`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/session-start.sh`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L131" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks_version_check_sh", + "label": "`hooks/version-check.sh`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`hooks/version-check.sh`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L158" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_plugin_json", + "label": "`plugin.json`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`plugin.json`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L52" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_readme_md_rewritten_target_100_lines", + "label": "`README.md` (rewritten, target ~100 lines)", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`readme.md` (rewritten, target ~100 lines)", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L216" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_repo_layout", + "label": "Repo layout", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "repo layout", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L19" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_risks_and_mitigations", + "label": "Risks and mitigations", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "risks and mitigations", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L308" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "label": "session-continuity v0.2 \u2014 public release design", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session-continuity v0.2 \u2014 public release design", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_skills_session_continuity_skill_md", + "label": "`skills/session-continuity/SKILL.md`", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`skills/session-continuity/skill.md`", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L69" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_1_github_repo_setup", + "label": "Step 1 \u2014 GitHub repo setup", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 \u2014 github repo setup", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L278" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_2_local_install_smoke_test", + "label": "Step 2 \u2014 Local install smoke test", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 \u2014 local install smoke test", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L288" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_3_marketplace_submission", + "label": "Step 3 \u2014 Marketplace submission", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3 \u2014 marketplace submission", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L292" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_4_passive_promotion_only", + "label": "Step 4 \u2014 Passive promotion only", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 4 \u2014 passive promotion only", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L296" + }, + { + "id": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_5_ongoing_maintenance", + "label": "Step 5 \u2014 Ongoing maintenance", + "_origin": "ast", + "community": 4, + "community_name": "Component designs", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 5 \u2014 ongoing maintenance", + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L300" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics", + "label": "2026-05-21-end-session-heuristics.md", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-05-21-end-session-heuristics.md", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_acceptance_gate", + "label": "Acceptance gate", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "acceptance gate", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L159" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_dogfood_test_this_session", + "label": "Dogfood test \u2014 this session", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "dogfood test \u2014 this session", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L107" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_1_clean_repo_no_commits_since_last_primer_refresh", + "label": "Scenario 1 \u2014 clean repo, no commits since last primer refresh", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 1 \u2014 clean repo, no commits since last primer refresh", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_2_commits_without_matches", + "label": "Scenario 2 \u2014 commits without matches", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 2 \u2014 commits without matches", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L39" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_3_commit_with_stem_intersection_match", + "label": "Scenario 3 \u2014 commit with stem-intersection match", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 3 \u2014 commit with stem-intersection match", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L57" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_4_retry_burst_heuristic_a", + "label": "Scenario 4 \u2014 retry burst (Heuristic A)", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 4 \u2014 retry burst (heuristic a)", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L75" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_5_revert_reset_heuristic_b", + "label": "Scenario 5 \u2014 revert / reset (Heuristic B)", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 5 \u2014 revert / reset (heuristic b)", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L91" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_step_1_outcome", + "label": "Step 1 outcome", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 outcome", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L114" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_step_2_outcome", + "label": "Step 2 outcome", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 outcome", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L131" + }, + { + "id": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "label": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "_origin": "ast", + "community": 40, + "community_name": "Validation log \u2014 end-session heuristic pass (v0.6.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "validation log \u2014 end-session heuristic pass (v0.6.0)", + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification", + "label": "2026-09-01-learnings-hardening-verification.md", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-01-learnings-hardening-verification.md", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_0_a_bug_found_and_fixed_during_this_verification", + "label": "0. A bug found and fixed during this verification", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "0. a bug found and fixed during this verification", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L16" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_1_smoke_suites", + "label": "1. Smoke suites", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "1. smoke suites", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L99" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_2_step_2_3_adapted_scratch_repo_mechanical_verification", + "label": "2. Step 2/3 (adapted): scratch-repo mechanical verification", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "2. step 2/3 (adapted): scratch-repo mechanical verification", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L115" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_3_fresh_replay_against_real_transcripts_task_5_s_harness_re_run_now", + "label": "3. Fresh replay against real transcripts (Task 5's harness, re-run now)", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "3. fresh replay against real transcripts (task 5's harness, re-run now)", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L215" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_4_summary_what_held_what_didn_t_what_wasn_t_run", + "label": "4. Summary \u2014 what held, what didn't, what wasn't run", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "4. summary \u2014 what held, what didn't, what wasn't run", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L266" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_actual_run_post_fix_directly_in_zsh_no_bash_c_wrapper", + "label": "Actual run (post-fix, directly in zsh, no `bash -c` wrapper)", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "actual run (post-fix, directly in zsh, no `bash -c` wrapper)", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L166" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_before_after_candidate_counts", + "label": "Before/after candidate counts", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "before/after candidate counts", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L250" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_the_adaptation_stated_plainly", + "label": "The adaptation, stated plainly", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the adaptation, stated plainly", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L117" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_the_four_end_to_end_invariants_plan_step_3", + "label": "The four end-to-end invariants (plan Step 3)", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the four end-to-end invariants (plan step 3)", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L199" + }, + { + "id": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_validation_log_learnings_generation_hardening_end_to_end_v0_25_0", + "label": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "_origin": "ast", + "community": 41, + "community_name": "Validation log \u2014 LEARNINGS-generation hardening, end-to-end (v0.25.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "validation log \u2014 learnings-generation hardening, end-to-end (v0.25.0)", + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_skill_do_not_commit_the_primer_by_itself", + "label": "Do NOT commit the primer by itself", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "do not commit the primer by itself", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L112" + }, + { + "id": "skills_session_continuity_skill_gate_mechanics_never_chain_git_add_and_git_commit_in_one_call", + "label": "Gate mechanics \u2014 never chain `git add` and `git commit` in one call", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "gate mechanics \u2014 never chain `git add` and `git commit` in one call", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L32" + }, + { + "id": "skills_session_continuity_skill_more_detail", + "label": "More detail", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "more detail", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L165" + }, + { + "id": "skills_session_continuity_skill_on_a_hard_won_bug_add_to_learnings_md", + "label": "On a hard-won bug \u2014 add to LEARNINGS.md", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "on a hard-won bug \u2014 add to learnings.md", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L143" + }, + { + "id": "skills_session_continuity_skill_on_every_substantive_commit_refresh_session_primer_md_in_the_same_commit", + "label": "On every substantive commit \u2014 refresh SESSION_PRIMER.md in the same commit", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "on every substantive commit \u2014 refresh session_primer.md in the same commit", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L83" + }, + { + "id": "skills_session_continuity_skill_quick_start_existing_primer_not_yet_split", + "label": "Quick start (existing primer, not yet split)", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "quick start (existing primer, not yet split)", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L73" + }, + { + "id": "skills_session_continuity_skill_quick_start_existing_project_with_these_files", + "label": "Quick start (existing project with these files)", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "quick start (existing project with these files)", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L65" + }, + { + "id": "skills_session_continuity_skill_quick_start_new_project", + "label": "Quick start (new project)", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "quick start (new project)", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L57" + }, + { + "id": "skills_session_continuity_skill_session_continuity", + "label": "Session Continuity", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session continuity", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L6" + }, + { + "id": "skills_session_continuity_skill_the_maintenance_rules_read_this_before_every_commit", + "label": "The maintenance rules (read this before every commit)", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the maintenance rules (read this before every commit)", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L81" + }, + { + "id": "skills_session_continuity_skill_when_to_use_this_skill", + "label": "When to use this skill", + "_origin": "ast", + "community": 42, + "community_name": "Session Continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "when to use this skill", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L47" + }, + { + "id": "skills_session_continuity_templates_project_context_end_to_end_check_real_integration", + "label": "End-to-end check (real integration)", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-to-end check (real integration)", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L49" + }, + { + "id": "skills_session_continuity_templates_project_context_ground_rules_how_to_work_here", + "label": "Ground rules (how to work here)", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "ground rules (how to work here)", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L8" + }, + { + "id": "skills_session_continuity_templates_project_context_if_you_get_stuck", + "label": "If you get stuck", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "if you get stuck", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L66" + }, + { + "id": "skills_session_continuity_templates_project_context_maintenance_your_responsibility", + "label": "Maintenance (your responsibility)", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "maintenance (your responsibility)", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L79" + }, + { + "id": "skills_session_continuity_templates_project_context_project_context_project_name", + "label": "Project Context \u2014 {{PROJECT_NAME}}", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "project context \u2014 {{project_name}}", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_project_context_repo_layout", + "label": "Repo layout", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "repo layout", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L19" + }, + { + "id": "skills_session_continuity_templates_project_context_test_expectations_these_must_stay_green", + "label": "Test expectations \u2014 these must stay green", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "test expectations \u2014 these must stay green", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L42" + }, + { + "id": "skills_session_continuity_templates_project_context_the_packages_modules", + "label": "The packages / modules", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the packages / modules", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L34" + }, + { + "id": "skills_session_continuity_templates_project_context_where_to_look_for_what", + "label": "Where to look for what", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "where to look for what", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L60" + }, + { + "id": "skills_session_continuity_templates_project_context_workflow_conventions", + "label": "Workflow conventions", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "workflow conventions", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L53" + }, + { + "id": "skills_session_continuity_templates_project_context_working_directory", + "label": "Working directory", + "_origin": "ast", + "community": 43, + "community_name": "Project Context \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "working directory", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L25" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan", + "label": "2026-09-02-end-session-step2-rendering-plan.md", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-02-end-session-step2-rendering-plan.md", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_end_session_step_2_rendering_and_reference_relocation_implementation_plan", + "label": "end-session Step 2 \u2014 rendering and reference relocation \u2014 Implementation Plan", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-session step 2 \u2014 rendering and reference relocation \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L27" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L15" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_1_resolve_transcript_sh", + "label": "Task 1: `resolve-transcript.sh`", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `resolve-transcript.sh`", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L41" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_2_candidate_render_sh", + "label": "Task 2: `candidate-render.sh`", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `candidate-render.sh`", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L211" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_3_relocate_heuristics_documentation_to_heuristics_md", + "label": "Task 3: Relocate heuristics documentation to `HEURISTICS.md`", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: relocate heuristics documentation to `heuristics.md`", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L442" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_4_rewrite_commands_end_session_md_step_2", + "label": "Task 4: Rewrite `commands/end-session.md` Step 2", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: rewrite `commands/end-session.md` step 2", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L619" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_5_on_demand_transcript_resolution_in_step_4", + "label": "Task 5: On-demand transcript resolution in Step 4", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: on-demand transcript resolution in step 4", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L972" + }, + { + "id": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_6_full_regression_pass_and_changelog", + "label": "Task 6: Full regression pass and changelog", + "_origin": "ast", + "community": 44, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: full regression pass and changelog", + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L1070" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library", + "label": "2026-09-03-shared-mechanics-library.md", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-03-shared-mechanics-library.md", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_determinism_phase_3_shared_mechanics_library_implementation_plan", + "label": "Determinism Phase 3 \u2014 shared mechanics library \u2014 Implementation Plan", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 3 \u2014 shared mechanics library \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L27" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L15" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_1_perf_log_sh_add_mark_and_since", + "label": "Task 1: `perf-log.sh` \u2014 add `mark` and `since`", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `perf-log.sh` \u2014 add `mark` and `since`", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L44" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_2_primer_status_sh", + "label": "Task 2: `primer-status.sh`", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `primer-status.sh`", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L356" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_3_wire_primer_status_sh_into_hooks_session_start_sh", + "label": "Task 3: Wire `primer-status.sh` into `hooks/session-start.sh`", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: wire `primer-status.sh` into `hooks/session-start.sh`", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L542" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_4_wire_primer_status_sh_into_commands_primer_md_check_mode", + "label": "Task 4: Wire `primer-status.sh` into `commands/primer.md` check mode", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: wire `primer-status.sh` into `commands/primer.md` check mode", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L635" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_5_collapse_the_four_epoch_blocks_in_commands_end_session_md", + "label": "Task 5: Collapse the four epoch blocks in `commands/end-session.md`", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: collapse the four epoch blocks in `commands/end-session.md`", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L737" + }, + { + "id": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_6_doc_pointers_regression_pass_changelog", + "label": "Task 6: Doc pointers, regression pass, changelog", + "_origin": "ast", + "community": 45, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: doc pointers, regression pass, changelog", + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L1040" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics", + "label": "2026-09-07-determinism-phase-5-backlog-mechanics.md", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_determinism_phase_5_backlog_mechanics_and_the_commit_overlap_gate_implementation_plan", + "label": "Determinism Phase 5 \u2014 backlog mechanics and the commit-overlap gate \u2014 Implementation Plan", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 5 \u2014 backlog mechanics and the commit-overlap gate \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L28" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L15" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_1_fix_candidate_extract_jq_s_overlap_closes_40", + "label": "Task 1: Fix `candidate-extract.jq`'s `overlap()` (closes `#40`)", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: fix `candidate-extract.jq`'s `overlap()` (closes `#40`)", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L47" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_2_backlog_item_sh_mint_tag_in_use_renumber", + "label": "Task 2: `backlog-item.sh` \u2014 `mint` / `tag-in-use` / `renumber`", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `backlog-item.sh` \u2014 `mint` / `tag-in-use` / `renumber`", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L179" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_3_commit_overlap_sh_tokenize_stopword_drop_threshold_intersection", + "label": "Task 3: `commit-overlap.sh` \u2014 tokenize + stopword-drop + threshold intersection", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: `commit-overlap.sh` \u2014 tokenize + stopword-drop + threshold intersection", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L432" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_4_wire_commands_primer_md_to_backlog_item_sh", + "label": "Task 4: Wire `commands/primer.md` to `backlog-item.sh`", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: wire `commands/primer.md` to `backlog-item.sh`", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L605" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_5_wire_commands_end_session_md_to_commit_overlap_sh", + "label": "Task 5: Wire `commands/end-session.md` to `commit-overlap.sh`", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: wire `commands/end-session.md` to `commit-overlap.sh`", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L776" + }, + { + "id": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_6_docs_backlog_changelog_version_bump", + "label": "Task 6: Docs, backlog, changelog, version bump", + "_origin": "ast", + "community": 46, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: docs, backlog, changelog, version bump", + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L922" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization", + "label": "2026-09-08-docguard-generalization.md", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-08-docguard-generalization.md", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "label": "Docguard Generalization Implementation Plan", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "docguard generalization implementation plan", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L67" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L27" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_1_parser_library_empty_missing_file", + "label": "Task 1: Parser library \u2014 empty/missing file", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: parser library \u2014 empty/missing file", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L90" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_2_parser_single_complete_entry_quoted_and_bare_values", + "label": "Task 2: Parser \u2014 single complete entry, quoted and bare values", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: parser \u2014 single complete entry, quoted and bare values", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L228" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_3_parser_multiple_entries_comments_blank_lines", + "label": "Task 3: Parser \u2014 multiple entries, comments, blank lines", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: parser \u2014 multiple entries, comments, blank lines", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L301" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_4_parser_invalid_entries_incomplete_or_in_claim_pattern_are_dropped_with_a_warning_don_t_corrupt_neighbors", + "label": "Task 4: Parser \u2014 invalid entries (incomplete, or `%` in claim_pattern) are dropped with a warning, don't corrupt neighbors", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: parser \u2014 invalid entries (incomplete, or `%` in claim_pattern) are dropped with a warning, don't corrupt neighbors", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L348" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_5_wire_the_parser_into_post_merge_preserve_legacy_fallback", + "label": "Task 5: Wire the parser into `post-merge`, preserve legacy fallback", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: wire the parser into `post-merge`, preserve legacy fallback", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L435" + }, + { + "id": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_6_update_the_design_sketch_doc_in_this_repo", + "label": "Task 6: Update the design sketch doc in this repo", + "_origin": "ast", + "community": 47, + "community_name": "Docguard Generalization Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: update the design sketch doc in this repo", + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L687" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design", + "label": "2026-07-30-outstanding-items-verification-design.md", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-07-30-outstanding-items-verification-design.md", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_constraint_that_shapes_the_design", + "label": "Constraint that shapes the design", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "constraint that shapes the design", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L15" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_decisions_from_brainstorming", + "label": "Decisions (from brainstorming)", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "decisions (from brainstorming)", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L33" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "label": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_edge_cases", + "label": "Edge cases", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "edge cases", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L123" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_placement_runs_in_step_1_above_the_drift_branch_reported_in_step_3", + "label": "Placement \u2014 runs in Step 1 (above the drift branch), reported in Step 3", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "placement \u2014 runs in step 1 (above the drift branch), reported in step 3", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L81" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L6" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_scope", + "label": "Scope", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scope", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L135" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_validation", + "label": "Validation", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "validation", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L143" + }, + { + "id": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_verdicts", + "label": "Verdicts", + "_origin": "ast", + "community": 48, + "community_name": "Design \u2014 outstanding-items code verification in `/session-continuity:end-session`", + "file_type": "document", + "node_kind": "heading", + "norm_label": "verdicts", + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L61" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design", + "label": "2026-08-17-performance-logging-design.md", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-17-performance-logging-design.md", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_mechanism_1_shipped_hooks_wrapper_not_inline", + "label": "Mechanism 1 \u2014 shipped hooks (wrapper, not inline)", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "mechanism 1 \u2014 shipped hooks (wrapper, not inline)", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L102" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_mechanism_2_slash_commands_self_reported", + "label": "Mechanism 2 \u2014 slash commands (self-reported)", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "mechanism 2 \u2014 slash commands (self-reported)", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L144" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_mechanism_3_shared_writer", + "label": "Mechanism 3 \u2014 shared writer", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "mechanism 3 \u2014 shared writer", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L245" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "label": "Per-repo performance logging \u2014 design", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "per-repo performance logging \u2014 design", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L10" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_schema", + "label": "Schema", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "schema", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L68" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_scope", + "label": "Scope", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scope", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L20" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_storage", + "label": "Storage", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "storage", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L34" + }, + { + "id": "meta_superpowers_specs_2026_08_17_performance_logging_design_testing_plan_not_yet_executed_nothing_in_this_spec_is_implemented", + "label": "Testing plan (not yet executed \u2014 nothing in this spec is implemented)", + "_origin": "ast", + "community": 49, + "community_name": "Per-repo performance logging \u2014 design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing plan (not yet executed \u2014 nothing in this spec is implemented)", + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L263" + }, + { + "id": "contributing_authoring_conventions", + "label": "Authoring conventions", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "authoring conventions", + "source_file": "CONTRIBUTING.md", + "source_location": "L231" + }, + { + "id": "contributing_before_you_start", + "label": "Before you start", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "before you start", + "source_file": "CONTRIBUTING.md", + "source_location": "L19" + }, + { + "id": "contributing_branching", + "label": "Branching", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "branching", + "source_file": "CONTRIBUTING.md", + "source_location": "L163" + }, + { + "id": "contributing_clone_and_install_locally", + "label": "Clone and install locally", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "clone and install locally", + "source_file": "CONTRIBUTING.md", + "source_location": "L35" + }, + { + "id": "contributing_code_review", + "label": "Code review", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "code review", + "source_file": "CONTRIBUTING.md", + "source_location": "L222" + }, + { + "id": "contributing_commits", + "label": "Commits", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "commits", + "source_file": "CONTRIBUTING.md", + "source_location": "L173" + }, + { + "id": "contributing_contributing_to_session_continuity", + "label": "Contributing to session-continuity", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "contributing to session-continuity", + "source_file": "CONTRIBUTING.md", + "source_location": "L1" + }, + { + "id": "contributing_development_workflow", + "label": "Development workflow", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "development workflow", + "source_file": "CONTRIBUTING.md", + "source_location": "L161" + }, + { + "id": "contributing_filing_good_issues", + "label": "Filing good issues", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "filing good issues", + "source_file": "CONTRIBUTING.md", + "source_location": "L281" + }, + { + "id": "contributing_hook_smoke_tests", + "label": "Hook smoke tests", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hook smoke tests", + "source_file": "CONTRIBUTING.md", + "source_location": "L63" + }, + { + "id": "contributing_hooks_hooks_sh", + "label": "Hooks (`hooks/*.sh`)", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hooks (`hooks/*.sh`)", + "source_file": "CONTRIBUTING.md", + "source_location": "L241" + }, + { + "id": "contributing_license_and_attribution", + "label": "License and attribution", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "license and attribution", + "source_file": "CONTRIBUTING.md", + "source_location": "L292" + }, + { + "id": "contributing_local_development", + "label": "Local development", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "local development", + "source_file": "CONTRIBUTING.md", + "source_location": "L27" + }, + { + "id": "contributing_prerequisites", + "label": "Prerequisites", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "prerequisites", + "source_file": "CONTRIBUTING.md", + "source_location": "L29" + }, + { + "id": "contributing_project_structure", + "label": "Project structure", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "project structure", + "source_file": "CONTRIBUTING.md", + "source_location": "L99" + }, + { + "id": "contributing_pull_requests", + "label": "Pull requests", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "pull requests", + "source_file": "CONTRIBUTING.md", + "source_location": "L211" + }, + { + "id": "contributing_questions", + "label": "Questions", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "questions", + "source_file": "CONTRIBUTING.md", + "source_location": "L300" + }, + { + "id": "contributing_release_process", + "label": "Release process", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "release process", + "source_file": "CONTRIBUTING.md", + "source_location": "L267" + }, + { + "id": "contributing_run_the_plugin_against_a_scratch_repo", + "label": "Run the plugin against a scratch repo", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "run the plugin against a scratch repo", + "source_file": "CONTRIBUTING.md", + "source_location": "L47" + }, + { + "id": "contributing_scope_first", + "label": "Scope first", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scope first", + "source_file": "CONTRIBUTING.md", + "source_location": "L5" + }, + { + "id": "contributing_slash_commands_commands_md", + "label": "Slash commands (`commands/*.md`)", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "slash commands (`commands/*.md`)", + "source_file": "CONTRIBUTING.md", + "source_location": "L233" + }, + { + "id": "contributing_specs_and_plans_for_non_trivial_changes", + "label": "Specs and plans (for non-trivial changes)", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "specs and plans (for non-trivial changes)", + "source_file": "CONTRIBUTING.md", + "source_location": "L192" + }, + { + "id": "contributing_templates_skills_session_continuity_templates_md", + "label": "Templates (`skills/session-continuity/templates/*.md`)", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "templates (`skills/session-continuity/templates/*.md`)", + "source_file": "CONTRIBUTING.md", + "source_location": "L250" + }, + { + "id": "contributing_testing", + "label": "Testing", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "CONTRIBUTING.md", + "source_location": "L200" + }, + { + "id": "contributing_writing_style", + "label": "Writing style", + "_origin": "ast", + "community": 5, + "community_name": "Contributing to session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "writing style", + "source_file": "CONTRIBUTING.md", + "source_location": "L256" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design", + "label": "2026-09-02-determinism-program-design.md", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-02-determinism-program-design.md", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "label": "Determinism program \u2014 Design", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism program \u2014 design", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_evidence", + "label": "Evidence", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "evidence", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L40" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L249" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_open_questions", + "label": "Open questions", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "open questions", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L258" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_phases", + "label": "Phases", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "phases", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L144" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_prompt_bytes_by_command", + "label": "Prompt bytes by command", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "prompt bytes by command", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L54" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_six_categories_of_avoidable_work", + "label": "Six categories of avoidable work", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "six categories of avoidable work", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L64" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_the_invariant", + "label": "The invariant", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the invariant", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L21" + }, + { + "id": "meta_superpowers_specs_2026_09_02_determinism_program_design_what_stays_model_work", + "label": "What stays model work", + "_origin": "ast", + "community": 50, + "community_name": "Determinism program \u2014 Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what stays model work", + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L114" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design", + "label": "2026-09-02-zero-turn-read-only-commands-design.md", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-02-zero-turn-read-only-commands-design.md", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_amendments_to_tasks_2_6", + "label": "Amendments to Tasks 2-6", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "amendments to tasks 2-6", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L148" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_cleanup", + "label": "Cleanup", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "cleanup", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L166" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_end_to_end_confirmation_blocking_a_real_slash_command_costs_zero_turns", + "label": "End-to-end confirmation: blocking a real slash command costs zero turns", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "end-to-end confirmation: blocking a real slash command costs zero turns", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L130" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_1_does_a_slash_command_reach_userpromptsubmit_and_what_is_prompt", + "label": "Measurement 1 \u2014 Does a slash command reach `UserPromptSubmit`, and what is `prompt`?", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "measurement 1 \u2014 does a slash command reach `userpromptsubmit`, and what is `prompt`?", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L37" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_2_what_is_command_name_for_a_plugin_scoped_command", + "label": "Measurement 2 \u2014 What is `command_name` for a plugin-scoped command?", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "measurement 2 \u2014 what is `command_name` for a plugin-scoped command?", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L53" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_3_how_does_a_multi_line_reason_render_and_where_does_it_truncate", + "label": "Measurement 3 \u2014 How does a multi-line `reason` render, and where does it truncate?", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "measurement 3 \u2014 how does a multi-line `reason` render, and where does it truncate?", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L75" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_4_is_suppressoriginalprompt_top_level_or_inside_hookspecificoutput", + "label": "Measurement 4 \u2014 Is `suppressOriginalPrompt` top-level or inside `hookSpecificOutput`?", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "measurement 4 \u2014 is `suppressoriginalprompt` top-level or inside `hookspecificoutput`?", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L94" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_method", + "label": "Method", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "method", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "label": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "_origin": "ast", + "community": 51, + "community_name": "Zero-turn read-only commands \u2014 Design (Task 1 measurement results)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "zero-turn read-only commands \u2014 design (task 1 measurement results)", + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design", + "label": "2026-09-08-primer-detect-design.md", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-08-primer-detect-design.md", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_architecture", + "label": "Architecture", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "architecture", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L38" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_context", + "label": "Context", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "context", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L5" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "label": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design \u2014 `primer-detect.sh`/`.jq` (determinism phase 6, sub-project a)", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_error_handling", + "label": "Error handling", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "error handling", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L133" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L178" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_output_contract", + "label": "Output contract", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "output contract", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L59" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L27" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_rollout", + "label": "Rollout", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "rollout", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L168" + }, + { + "id": "meta_superpowers_specs_2026_09_08_primer_detect_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 52, + "community_name": "Design \u2014 `primer-detect.sh`/`.jq` (Determinism Phase 6, sub-project A)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L145" + }, + { + "id": "hooks_derived_value_gate", + "label": "derived-value-gate.sh", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "derived-value-gate.sh", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_derived_value_gate_dvg_check_compare", + "label": "_dvg_check_compare()", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "_dvg_check_compare()", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L55" + }, + { + "id": "hooks_derived_value_gate_dvg_check_count", + "label": "_dvg_check_count()", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "_dvg_check_count()", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L47" + }, + { + "id": "hooks_derived_value_gate_dvg_check_duration", + "label": "_dvg_check_duration()", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "_dvg_check_duration()", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L39" + }, + { + "id": "hooks_derived_value_gate_dvg_check_verbatim", + "label": "_dvg_check_verbatim()", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "_dvg_check_verbatim()", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L63" + }, + { + "id": "hooks_derived_value_gate_dvg_deny", + "label": "_dvg_deny()", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "_dvg_deny()", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L32" + }, + { + "id": "hooks_derived_value_gate_gate_check", + "label": "gate_check()", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check()", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L72" + }, + { + "id": "hooks_derived_value_gate_gate_in_scope", + "label": "gate_in_scope()", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_in_scope()", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L25" + }, + { + "id": "hooks_derived_value_gate_sh__entry", + "label": "derived-value-gate.sh script", + "_origin": "ast", + "community": 53, + "community_name": "derived-value-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "derived-value-gate.sh script", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification", + "label": "plans/2026-07-30-outstanding-items-verification.md", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "plans/2026-07-30-outstanding-items-verification.md", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_execution_handoff", + "label": "Execution Handoff", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "execution handoff", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L398" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L25" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "label": "Outstanding-Items Verification Implementation Plan", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "outstanding-items verification implementation plan", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_self_review", + "label": "Self-Review", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L370" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_task_1_step_1_verification_sub_block_classify_verify_route", + "label": "Task 1: Step 1 verification sub-block (classify + verify + route)", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: step 1 verification sub-block (classify + verify + route)", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L39" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_task_2_step_3_checklist_row_re_derive_post_edit_example_notes", + "label": "Task 2: Step 3 checklist row (re-derive post-edit) + example + Notes", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: step 3 checklist row (re-derive post-edit) + example + notes", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L177" + }, + { + "id": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_task_3_validation_matrix_primer_refresh", + "label": "Task 3: Validation matrix + primer refresh", + "_origin": "ast", + "community": 54, + "community_name": "Outstanding-Items Verification Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: validation matrix + primer refresh", + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L308" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split", + "label": "2026-08-13-primer-volatile-stable-split.md", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-13-primer-volatile-stable-split.md", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L24" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_primer_volatile_stable_split_implementation_plan", + "label": "Primer volatile/stable split \u2014 Implementation Plan", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "primer volatile/stable split \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_1_new_project_context_md_template_trim_session_primer_md_template", + "label": "Task 1: New PROJECT_CONTEXT.md template + trim SESSION_PRIMER.md template", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: new project_context.md template + trim session_primer.md template", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L39" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_2_commands_primer_md_split_mode_detection_split_mode_init_mode_update", + "label": "Task 2: `commands/primer.md` \u2014 split-mode detection, Split mode, Init mode update", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `commands/primer.md` \u2014 split-mode detection, split mode, init mode update", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L227" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_3_commands_end_session_md_stage_project_context_md_when_touched", + "label": "Task 3: `commands/end-session.md` \u2014 stage PROJECT_CONTEXT.md when touched", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: `commands/end-session.md` \u2014 stage project_context.md when touched", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L364" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_4_skills_session_continuity_skill_md_doc_updates", + "label": "Task 4: `skills/session-continuity/SKILL.md` doc updates", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: `skills/session-continuity/skill.md` doc updates", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L409" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_5_dogfood_split_this_repo_s_own_primer_bump_version_changelog", + "label": "Task 5: Dogfood \u2014 split this repo's own primer, bump version, changelog", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: dogfood \u2014 split this repo's own primer, bump version, changelog", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L468" + }, + { + "id": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_6_manual_validation_pass", + "label": "Task 6: Manual validation pass", + "_origin": "ast", + "community": 55, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: manual validation pass", + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L567" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging", + "label": "validation/2026-08-17-performance-logging.md", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "page", + "norm_label": "validation/2026-08-17-performance-logging.md", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_acceptance_gate", + "label": "Acceptance gate", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "acceptance gate", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L323" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_concerns_found_during_this_validation", + "label": "Concerns found during this validation", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "concerns found during this validation", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L287" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_full_captured_log_all_4_runs_in_order", + "label": "Full captured log (all 4 runs, in order)", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "full captured log (all 4 runs, in order)", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L260" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_1_primer_init_mode_no_primer_exists", + "label": "Scenario 1 \u2014 Primer init mode (no primer exists)", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 1 \u2014 primer init mode (no primer exists)", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L24" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_2_primer_refresh_mode_unrelated_code_staged", + "label": "Scenario 2 \u2014 Primer refresh mode (unrelated code staged)", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 2 \u2014 primer refresh mode (unrelated code staged)", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L74" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_3_end_session_fast_path_nothing_changed_since_last_close_out", + "label": "Scenario 3 \u2014 end-session fast path (nothing changed since last close-out)", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 3 \u2014 end-session fast path (nothing changed since last close-out)", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L128" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_4_end_session_full_step_1_path_drift_appears_done_item", + "label": "Scenario 4 \u2014 end-session full Step 1 path (drift + appears-DONE item)", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scenario 4 \u2014 end-session full step 1 path (drift + appears-done item)", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L191" + }, + { + "id": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "label": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "_origin": "ast", + "community": 56, + "community_name": "Validation log \u2014 per-repo performance logging (v0.15.0)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "validation log \u2014 per-repo performance logging (v0.15.0)", + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_learnings_1_entry_title", + "label": "1. {{ENTRY_TITLE}}", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "1. {{entry_title}}", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L32" + }, + { + "id": "skills_session_continuity_templates_learnings_2_entry_title", + "label": "2. {{ENTRY_TITLE}}", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "2. {{entry_title}}", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L63" + }, + { + "id": "skills_session_continuity_templates_learnings_anti_patterns_we_were_tempted_by_and_rejected", + "label": "Anti-patterns we were tempted by (and rejected)", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "anti-patterns we were tempted by (and rejected)", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L82" + }, + { + "id": "skills_session_continuity_templates_learnings_checklist_for_a_fresh_dev_env_setup", + "label": "Checklist for a fresh dev-env setup", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "checklist for a fresh dev-env setup", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L92" + }, + { + "id": "skills_session_continuity_templates_learnings_layer_1_name", + "label": "{{LAYER_1_NAME}}", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "{{layer_1_name}}", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L22" + }, + { + "id": "skills_session_continuity_templates_learnings_layer_2_name", + "label": "{{LAYER_2_NAME}}", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "{{layer_2_name}}", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L60" + }, + { + "id": "skills_session_continuity_templates_learnings_learnings_project_name", + "label": "Learnings \u2014 {{PROJECT_NAME}}", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "learnings \u2014 {{project_name}}", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_learnings_security_incidents", + "label": "Security incidents", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "security incidents", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L70" + }, + { + "id": "skills_session_continuity_templates_learnings_symptoms_index", + "label": "Symptoms index", + "_origin": "ast", + "community": 57, + "community_name": "Learnings \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "symptoms index", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L11" + }, + { + "id": "hooks_lib_render", + "label": "render.sh", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "render.sh", + "source_file": "hooks/lib/render.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_render_check_sibling", + "label": "check_sibling()", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "check_sibling()", + "source_file": "hooks/lib/render.sh", + "source_location": "L36" + }, + { + "id": "hooks_lib_render_die_install", + "label": "die_install()", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "die_install()", + "source_file": "hooks/lib/render.sh", + "source_location": "L31" + }, + { + "id": "hooks_lib_render_render_backlog", + "label": "render_backlog()", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "render_backlog()", + "source_file": "hooks/lib/render.sh", + "source_location": "L44" + }, + { + "id": "hooks_lib_render_render_help", + "label": "render_help()", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "render_help()", + "source_file": "hooks/lib/render.sh", + "source_location": "L74" + }, + { + "id": "hooks_lib_render_render_learnings", + "label": "render_learnings()", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "render_learnings()", + "source_file": "hooks/lib/render.sh", + "source_location": "L54" + }, + { + "id": "hooks_lib_render_render_update", + "label": "render_update()", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "render_update()", + "source_file": "hooks/lib/render.sh", + "source_location": "L132" + }, + { + "id": "hooks_lib_render_sh__entry", + "label": "render.sh script", + "_origin": "ast", + "community": 58, + "community_name": "render.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "render.sh script", + "source_file": "hooks/lib/render.sh", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check", + "label": "2026-06-17-occurrence-counter-and-spike-check.md", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-06-17-occurrence-counter-and-spike-check.md", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_occurrence_counter_gate_spike_check_command_implementation_plan", + "label": "Occurrence-counter gate + spike-check command \u2014 Implementation Plan", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "occurrence-counter gate + spike-check command \u2014 implementation plan", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_self_review", + "label": "Self-Review", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L463" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_1_occurrence_gate_hook_smoke_runner", + "label": "Task 1: occurrence-gate hook + smoke runner", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: occurrence-gate hook + smoke runner", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L23" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_2_extend_learning_with_occurrence_count_invariant_fields", + "label": "Task 2: extend `/learning` with occurrence-count + invariant fields", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: extend `/learning` with occurrence-count + invariant fields", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L271" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_3_spike_check_command", + "label": "Task 3: `/spike-check` command", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: `/spike-check` command", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L320" + }, + { + "id": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_4_version_bump_readme_changelog_final_smoke", + "label": "Task 4: version bump, README, CHANGELOG, final smoke", + "_origin": "ast", + "community": 59, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: version bump, readme, changelog, final smoke", + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L379" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L19" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_n_title", + "label": "<N>. <Title>", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "<n>. <title>", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L433" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_quick_resumption_command", + "label": "Quick resumption command", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "quick resumption command", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1383" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_resumption_checklist_2026_04_27_pause_point", + "label": "Resumption checklist (2026-04-27 pause point)", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "resumption checklist (2026-04-27 pause point)", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1343" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_self_review", + "label": "Self-review", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1300" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "label": "session-continuity v0.2 Public Release Implementation Plan", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session-continuity v0.2 public release implementation plan", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_10_rewrite_readme_md", + "label": "Task 10: Rewrite `README.md`", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 10: rewrite `readme.md`", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L889" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_11_local_install_smoke_test", + "label": "Task 11: Local install smoke test", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 11: local install smoke test", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1009" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_12_publish_to_github", + "label": "Task 12: Publish to GitHub", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 12: publish to github", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1087" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_13_second_machine_install_verification", + "label": "Task 13: Second-machine install verification", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 13: second-machine install verification", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1164" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_14_submit_to_anthropic_plugin_marketplace", + "label": "Task 14: Submit to Anthropic plugin marketplace", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 14: submit to anthropic plugin marketplace", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1202" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_15_wrap_up_verify_everything_is_green", + "label": "Task 15: Wrap up \u2014 verify everything is green", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 15: wrap up \u2014 verify everything is green", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1249" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_1_prep_git_init_and_safety_commit_of_current_state", + "label": "Task 1: Prep \u2014 git init and safety commit of current state", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: prep \u2014 git init and safety commit of current state", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L50" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_2_restructure_move_skill_and_templates_into_plugin_layout", + "label": "Task 2: Restructure \u2014 move skill and templates into plugin layout", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: restructure \u2014 move skill and templates into plugin layout", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L103" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_3_update_skill_md_tighten_description_and_add_plugin_affordances_note", + "label": "Task 3: Update SKILL.md \u2014 tighten description and add plugin-affordances note", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: update skill.md \u2014 tighten description and add plugin-affordances note", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L166" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_4_update_plugin_json_version_bump_homepage_repository", + "label": "Task 4: Update `plugin.json` \u2014 version bump, homepage, repository", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: update `plugin.json` \u2014 version bump, homepage, repository", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L218" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_5_create_session_continuity_primer_slash_command", + "label": "Task 5: Create `/session-continuity:primer` slash command", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 5: create `/session-continuity:primer` slash command", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L269" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_6_create_session_continuity_learning_slash_command", + "label": "Task 6: Create `/session-continuity:learning` slash command", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 6: create `/session-continuity:learning` slash command", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L368" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_7_create_hook_scripts_and_hooks_json", + "label": "Task 7: Create hook scripts and `hooks.json`", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 7: create hook scripts and `hooks.json`", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L480" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_8_create_github_workflows_release_yml", + "label": "Task 8: Create `.github/workflows/release.yml`", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 8: create `.github/workflows/release.yml`", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L770" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_9_write_changelog_md", + "label": "Task 9: Write `CHANGELOG.md`", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 9: write `changelog.md`", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L835" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_what_s_done", + "label": "What's done", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what's done", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1345" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_what_s_still_pending", + "label": "What's still pending", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what's still pending", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1372" + }, + { + "id": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_what_was_learned_during_task_11_smoke_testing_and_fixed", + "label": "What was learned during Task 11 smoke testing (and fixed)", + "_origin": "ast", + "community": 6, + "community_name": "session-continuity v0.2 Public Release Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what was learned during task 11 smoke testing (and fixed)", + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1365" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate", + "label": "2026-06-17-proven-gate.md", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-06-17-proven-gate.md", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate_execution_handoff", + "label": "Execution Handoff", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "execution handoff", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L373" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate_proven_gate_implementation_plan", + "label": "Proven-gate Implementation Plan", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "proven-gate implementation plan", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate_self_review", + "label": "Self-Review", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-review", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L356" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate_task_1_the_proven_gate_hook_hermetic_smoke", + "label": "Task 1: The proven-gate hook + hermetic smoke", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: the proven-gate hook + hermetic smoke", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L23" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate_task_2_wire_the_hook_into_hooks_json", + "label": "Task 2: Wire the hook into hooks.json", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: wire the hook into hooks.json", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L254" + }, + { + "id": "meta_superpowers_plans_2026_06_17_proven_gate_task_3_version_bump_changelog_readme", + "label": "Task 3: Version bump + CHANGELOG + README", + "_origin": "ast", + "community": 60, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: version bump + changelog + readme", + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L296" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog", + "label": "2026-09-07-github-issues-backlog.md", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-07-github-issues-backlog.md", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog_github_issues_backlog_implementation_plan", + "label": "GitHub Issues Backlog Implementation Plan", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "github issues backlog implementation plan", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog_spec_coverage", + "label": "Spec coverage", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "spec coverage", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L222" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_1_backlog_issues_sh_smoke", + "label": "Task 1: `backlog-issues.sh` + smoke", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `backlog-issues.sh` + smoke", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L24" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_2_wire_render_session_start_primer_status_rewrite_smokes_delete_awk", + "label": "Task 2: Wire render / session-start / primer-status; rewrite smokes; delete awk", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: wire render / session-start / primer-status; rewrite smokes; delete awk", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L82" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_3_commands_skill_docs_template_deletion_version_bump", + "label": "Task 3: Commands, skill, docs, template deletion, version bump", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: commands, skill, docs, template deletion, version bump", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L170" + }, + { + "id": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_4_migrate_this_repo", + "label": "Task 4: Migrate this repo", + "_origin": "ast", + "community": 61, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: migrate this repo", + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L202" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design", + "label": "2026-08-12-session-start-outstanding-items-design.md", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-12-session-start-outstanding-items-design.md", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_decision", + "label": "Decision", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "heading", + "norm_label": "decision", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L15" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "label": "Design \u2014 SessionStart surfaces outstanding items", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design \u2014 sessionstart surfaces outstanding items", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_implementation_notes", + "label": "Implementation notes", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "heading", + "norm_label": "implementation notes", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L67" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L99" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_output_shape", + "label": "Output shape", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "heading", + "norm_label": "output shape", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L44" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L6" + }, + { + "id": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 62, + "community_name": "Design \u2014 SessionStart surfaces outstanding items", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L82" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design", + "label": "2026-09-09-primer-init-derive-design.md", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-09-primer-init-derive-design.md", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_architecture", + "label": "Architecture", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "architecture", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L54" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_context", + "label": "Context", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "context", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L3" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "label": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 6, sub-project d \u2014 `primer-init-derive.sh`/`.jq` design", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L242" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_output_contract", + "label": "Output contract", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "output contract", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L120" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L12" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 63, + "community_name": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Design", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L210" + }, + { + "id": "skills_session_continuity_heuristics", + "label": "HEURISTICS.md", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "page", + "norm_label": "heuristics.md", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_heuristics_heuristic_a_retry_burst", + "label": "Heuristic A \u2014 retry burst", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "heuristic a \u2014 retry burst", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L23" + }, + { + "id": "skills_session_continuity_heuristics_heuristic_b_revert_reset", + "label": "Heuristic B \u2014 revert / reset", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "heuristic b \u2014 revert / reset", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L48" + }, + { + "id": "skills_session_continuity_heuristics_heuristic_c_error_recurrence", + "label": "Heuristic C \u2014 error recurrence", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "heuristic c \u2014 error recurrence", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L71" + }, + { + "id": "skills_session_continuity_heuristics_heuristic_d_fix_burst", + "label": "Heuristic D \u2014 fix burst", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "heuristic d \u2014 fix burst", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L89" + }, + { + "id": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "label": "LEARNINGS candidate heuristics (context-window fallback)", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "learnings candidate heuristics (context-window fallback)", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_heuristics_presentation_context_window_mode_only", + "label": "Presentation (context-window mode only)", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "presentation (context-window mode only)", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L104" + }, + { + "id": "skills_session_continuity_heuristics_privacy", + "label": "Privacy", + "_origin": "ast", + "community": 64, + "community_name": "LEARNINGS candidate heuristics (context-window fallback)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "privacy", + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L15" + }, + { + "id": "skills_session_continuity_reference_complementary_mechanisms", + "label": "Complementary mechanisms", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "complementary mechanisms", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L94" + }, + { + "id": "skills_session_continuity_reference_customization_guidance", + "label": "Customization guidance", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "customization guidance", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L70" + }, + { + "id": "skills_session_continuity_reference_for_team_wide_use", + "label": "For team-wide use", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "for team-wide use", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L79" + }, + { + "id": "skills_session_continuity_reference_hooks_and_content_gates", + "label": "Hooks and content gates", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "hooks and content gates", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L8" + }, + { + "id": "skills_session_continuity_reference_philosophy", + "label": "Philosophy", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "philosophy", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L100" + }, + { + "id": "skills_session_continuity_reference_red_flags_when_not_to_use", + "label": "Red flags \u2014 when NOT to use", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "red flags \u2014 when not to use", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L88" + }, + { + "id": "skills_session_continuity_reference_session_continuity_reference", + "label": "Session Continuity \u2014 Reference", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session continuity \u2014 reference", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_reference_what_goes_where_a_decision_tree", + "label": "What goes where \u2014 a decision tree", + "_origin": "ast", + "community": 65, + "community_name": "Session Continuity \u2014 Reference", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what goes where \u2014 a decision tree", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L50" + }, + { + "id": "hooks_lib_learnings_index", + "label": "learnings-index.sh", + "_origin": "ast", + "community": 66, + "community_name": "learnings-index.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "learnings-index.sh", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_learnings_index_check_siblings", + "label": "check_siblings()", + "_origin": "ast", + "community": 66, + "community_name": "learnings-index.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "check_siblings()", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L46" + }, + { + "id": "hooks_lib_learnings_index_count_entries", + "label": "count_entries()", + "_origin": "ast", + "community": 66, + "community_name": "learnings-index.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "count_entries()", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L56" + }, + { + "id": "hooks_lib_learnings_index_die_install", + "label": "die_install()", + "_origin": "ast", + "community": 66, + "community_name": "learnings-index.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "die_install()", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L40" + }, + { + "id": "hooks_lib_learnings_index_reindex", + "label": "reindex()", + "_origin": "ast", + "community": 66, + "community_name": "learnings-index.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "reindex()", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L66" + }, + { + "id": "hooks_lib_learnings_index_report", + "label": "report()", + "_origin": "ast", + "community": 66, + "community_name": "learnings-index.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "report()", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L60" + }, + { + "id": "hooks_lib_learnings_index_sh__entry", + "label": "learnings-index.sh script", + "_origin": "ast", + "community": 66, + "community_name": "learnings-index.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "learnings-index.sh script", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_08_primer_detect", + "label": "2026-09-08-primer-detect.md", + "_origin": "ast", + "community": 67, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-08-primer-detect.md", + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_08_primer_detect_determinism_phase_6_sub_project_a_primer_detect_sh_jq_implementation_plan", + "label": "Determinism Phase 6, sub-project A \u2014 `primer-detect.sh`/`.jq` Implementation Plan", + "_origin": "ast", + "community": 67, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 6, sub-project a \u2014 `primer-detect.sh`/`.jq` implementation plan", + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_08_primer_detect_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 67, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L24" + }, + { + "id": "meta_superpowers_plans_2026_09_08_primer_detect_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 67, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_09_08_primer_detect_task_1_hooks_lib_primer_detect_jq_hooks_lib_primer_detect_sh", + "label": "Task 1: `hooks/lib/primer-detect.jq` + `hooks/lib/primer-detect.sh`", + "_origin": "ast", + "community": 67, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `hooks/lib/primer-detect.jq` + `hooks/lib/primer-detect.sh`", + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L38" + }, + { + "id": "meta_superpowers_plans_2026_09_08_primer_detect_task_2_commands_primer_md_call_the_script", + "label": "Task 2: `commands/primer.md` \u2014 call the script", + "_origin": "ast", + "community": 67, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `commands/primer.md` \u2014 call the script", + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L428" + }, + { + "id": "meta_superpowers_plans_2026_09_08_primer_detect_task_3_doc_pointers_regression_pass_changelog", + "label": "Task 3: Doc pointers, regression pass, changelog", + "_origin": "ast", + "community": 67, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: doc pointers, regression pass, changelog", + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L627" + }, + { + "id": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate", + "label": "2026-09-09-determinism-phase-7-derived-value-gate.md", + "_origin": "ast", + "community": 68, + "community_name": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_determinism_phase_7_derived_value_gate_implementation_plan", + "label": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "_origin": "ast", + "community": 68, + "community_name": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 7 \u2014 derived-value gate implementation plan", + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 68, + "community_name": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L77" + }, + { + "id": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_1_fix_54_converge_end_session_md_s_drift_check_rerun_onto_test_count_rerun_sh", + "label": "Task 1: Fix `#54` \u2014 converge `end-session.md`'s drift-check rerun onto `test-count-rerun.sh`", + "_origin": "ast", + "community": 68, + "community_name": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: fix `#54` \u2014 converge `end-session.md`'s drift-check rerun onto `test-count-rerun.sh`", + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L117" + }, + { + "id": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_2_hooks_derived_value_gate_sh_smoke_test", + "label": "Task 2: `hooks/derived-value-gate.sh` + smoke test", + "_origin": "ast", + "community": 68, + "community_name": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `hooks/derived-value-gate.sh` + smoke test", + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L272" + }, + { + "id": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_3_wire_into_hooks_json", + "label": "Task 3: Wire into `hooks.json`", + "_origin": "ast", + "community": 68, + "community_name": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: wire into `hooks.json`", + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L493" + }, + { + "id": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_4_doc_pointers_security_md_correction_changelog_version_bump", + "label": "Task 4: Doc pointers, `SECURITY.md` correction, changelog, version bump", + "_origin": "ast", + "community": 68, + "community_name": "Determinism Phase 7 \u2014 Derived-Value Gate Implementation Plan", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 4: doc pointers, `security.md` correction, changelog, version bump", + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L544" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_init_derive", + "label": "2026-09-09-primer-init-derive.md", + "_origin": "ast", + "community": 69, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-09-primer-init-derive.md", + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_init_derive_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_implementation_plan", + "label": "Determinism Phase 6, sub-project D \u2014 `primer-init-derive.sh`/`.jq` Implementation Plan", + "_origin": "ast", + "community": 69, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 6, sub-project d \u2014 `primer-init-derive.sh`/`.jq` implementation plan", + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_init_derive_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 69, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L74" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_init_derive_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 69, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L30" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_init_derive_task_1_hooks_lib_primer_init_derive_jq_hooks_lib_primer_init_derive_sh", + "label": "Task 1: `hooks/lib/primer-init-derive.jq` + `hooks/lib/primer-init-derive.sh`", + "_origin": "ast", + "community": 69, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `hooks/lib/primer-init-derive.jq` + `hooks/lib/primer-init-derive.sh`", + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L88" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_init_derive_task_2_commands_primer_md_call_the_script", + "label": "Task 2: `commands/primer.md` \u2014 call the script", + "_origin": "ast", + "community": 69, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `commands/primer.md` \u2014 call the script", + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L505" + }, + { + "id": "meta_superpowers_plans_2026_09_09_primer_init_derive_task_3_doc_pointers_regression_pass_changelog", + "label": "Task 3: Doc pointers, regression pass, changelog", + "_origin": "ast", + "community": 69, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: doc pointers, regression pass, changelog", + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L661" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design", + "label": "2026-05-21-end-session-heuristic-pass-design.md", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-05-21-end-session-heuristic-pass-design.md", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_1_outstanding_items_match_step_1_overlay", + "label": "\u00a71 outstanding-items match (Step 1 overlay)", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "\u00a71 outstanding-items match (step 1 overlay)", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L69" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_5_learnings_heuristics_step_2_replacement", + "label": "\u00a75 LEARNINGS heuristics (Step 2 replacement)", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "\u00a75 learnings heuristics (step 2 replacement)", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L98" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_acceptance_criteria", + "label": "Acceptance criteria", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "acceptance criteria", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L305" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_architecture", + "label": "Architecture", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "architecture", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L44" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_cap_behavior", + "label": "Cap behavior", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "cap behavior", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L201" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_compatibility", + "label": "Compatibility", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L315" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "label": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design \u2014 `/session-continuity:end-session` heuristic pass", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_dogfood_test", + "label": "Dogfood test", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "dogfood test", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L297" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_edge_cases", + "label": "Edge cases", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "edge cases", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L238" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_goal", + "label": "Goal", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goal", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L29" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_heuristic_specs", + "label": "Heuristic specs", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "heuristic specs", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L67" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_manual_validation_matrix", + "label": "Manual validation matrix", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "manual validation matrix", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L272" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L35" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_presentation", + "label": "Presentation", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "presentation", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L151" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L7" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_refusals", + "label": "Refusals", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "refusals", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L141" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_step_1_refresh_output", + "label": "Step 1 (Refresh) output", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 (refresh) output", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L153" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_step_2_session_reflection_output", + "label": "Step 2 (Session reflection) output", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 (session reflection) output", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L174" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_step_3_checklist_updates", + "label": "Step 3 checklist updates", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 3 checklist updates", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L207" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_testing_validation", + "label": "Testing + validation", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing + validation", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L267" + }, + { + "id": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_transcript_resolution", + "label": "Transcript resolution", + "_origin": "ast", + "community": 7, + "community_name": "Design \u2014 `/session-continuity:end-session` heuristic pass", + "file_type": "document", + "node_kind": "heading", + "norm_label": "transcript resolution", + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L214" + }, + { + "id": "meta_superpowers_plans_2026_09_09_test_count_rerun", + "label": "2026-09-09-test-count-rerun.md", + "_origin": "ast", + "community": 70, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-09-test-count-rerun.md", + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_09_test_count_rerun_determinism_phase_6_sub_project_b_test_count_rerun_sh_jq_implementation_plan", + "label": "Determinism Phase 6, sub-project B \u2014 `test-count-rerun.sh`/`.jq` Implementation Plan", + "_origin": "ast", + "community": 70, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "determinism phase 6, sub-project b \u2014 `test-count-rerun.sh`/`.jq` implementation plan", + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_09_09_test_count_rerun_file_structure", + "label": "File Structure", + "_origin": "ast", + "community": 70, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "file structure", + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L25" + }, + { + "id": "meta_superpowers_plans_2026_09_09_test_count_rerun_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 70, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L13" + }, + { + "id": "meta_superpowers_plans_2026_09_09_test_count_rerun_task_1_hooks_lib_test_count_rerun_jq_hooks_lib_test_count_rerun_sh", + "label": "Task 1: `hooks/lib/test-count-rerun.jq` + `hooks/lib/test-count-rerun.sh`", + "_origin": "ast", + "community": 70, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: `hooks/lib/test-count-rerun.jq` + `hooks/lib/test-count-rerun.sh`", + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L39" + }, + { + "id": "meta_superpowers_plans_2026_09_09_test_count_rerun_task_2_commands_primer_md_call_the_script", + "label": "Task 2: `commands/primer.md` \u2014 call the script", + "_origin": "ast", + "community": 70, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 2: `commands/primer.md` \u2014 call the script", + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L506" + }, + { + "id": "meta_superpowers_plans_2026_09_09_test_count_rerun_task_3_doc_pointers_regression_pass_changelog", + "label": "Task 3: Doc pointers, regression pass, changelog", + "_origin": "ast", + "community": 70, + "community_name": "File Structure", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 3: doc pointers, regression pass, changelog", + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L601" + }, + { + "id": "hooks_lib_candidate_extract", + "label": "candidate-extract.sh", + "_origin": "ast", + "community": 71, + "community_name": "candidate-extract.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "candidate-extract.sh", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_candidate_extract_emit", + "label": "emit()", + "_origin": "ast", + "community": 71, + "community_name": "candidate-extract.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "emit()", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L52" + }, + { + "id": "hooks_lib_candidate_extract_finish", + "label": "finish()", + "_origin": "ast", + "community": 71, + "community_name": "candidate-extract.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "finish()", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L39" + }, + { + "id": "hooks_lib_candidate_extract_json_escape", + "label": "json_escape()", + "_origin": "ast", + "community": 71, + "community_name": "candidate-extract.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "json_escape()", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L35" + }, + { + "id": "hooks_lib_candidate_extract_mtime_epoch", + "label": "mtime_epoch()", + "_origin": "ast", + "community": 71, + "community_name": "candidate-extract.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "mtime_epoch()", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L59" + }, + { + "id": "hooks_lib_candidate_extract_sh__entry", + "label": "candidate-extract.sh script", + "_origin": "ast", + "community": 71, + "community_name": "candidate-extract.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "candidate-extract.sh script", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L1" + }, + { + "id": "meta_administrative_marketplace_submission", + "label": "marketplace-submission.md", + "_origin": "ast", + "community": 72, + "community_name": "Anthropic plugin marketplace submission", + "file_type": "document", + "node_kind": "page", + "norm_label": "marketplace-submission.md", + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L1" + }, + { + "id": "meta_administrative_marketplace_submission_anthropic_plugin_marketplace_submission", + "label": "Anthropic plugin marketplace submission", + "_origin": "ast", + "community": 72, + "community_name": "Anthropic plugin marketplace submission", + "file_type": "document", + "node_kind": "heading", + "norm_label": "anthropic plugin marketplace submission", + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L1" + }, + { + "id": "meta_administrative_marketplace_submission_any_telemetry_external_calls", + "label": "Any telemetry / external calls?", + "_origin": "ast", + "community": 72, + "community_name": "Anthropic plugin marketplace submission", + "file_type": "document", + "node_kind": "heading", + "norm_label": "any telemetry / external calls?", + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L21" + }, + { + "id": "meta_administrative_marketplace_submission_pre_filled_from_claude_plugin_plugin_json", + "label": "Pre-filled from `.claude-plugin/plugin.json`", + "_origin": "ast", + "community": 72, + "community_name": "Anthropic plugin marketplace submission", + "file_type": "document", + "node_kind": "heading", + "norm_label": "pre-filled from `.claude-plugin/plugin.json`", + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L27" + }, + { + "id": "meta_administrative_marketplace_submission_what_does_it_do_why_would_i_install_it", + "label": "What does it do / why would I install it?", + "_origin": "ast", + "community": 72, + "community_name": "Anthropic plugin marketplace submission", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what does it do / why would i install it?", + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L3" + }, + { + "id": "meta_administrative_marketplace_submission_who_s_the_target_user", + "label": "Who's the target user?", + "_origin": "ast", + "community": 72, + "community_name": "Anthropic plugin marketplace submission", + "file_type": "document", + "node_kind": "heading", + "norm_label": "who's the target user?", + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L15" + }, + { + "id": "skills_session_continuity_skill", + "label": "SKILL.md", + "_origin": "ast", + "community": 73, + "community_name": "SKILL.md", + "file_type": "document", + "frontmatter": { + "name": "session-continuity", + "description": "Establish and maintain cross-session memory for a project via four in-repo docs \u2014 .session-continuity/SESSION_PRIMER.md (current state, refreshed alongside substantive commits), .session-continuity/ROADMAP.md (strategic direction), .session-continuity/PROJECT_CONTEXT.md (stable repo context, changes rarely), and .session-continuity/LEARNINGS.md (append-only wisdom for 15+ min bugs) \u2014 plus GitHub Issues labeled backlog for the work queue. Use when starting, before commits, or after hard-won bugs." + }, + "node_kind": "page", + "norm_label": "skill.md", + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_reference", + "label": "REFERENCE.md", + "_origin": "ast", + "community": 73, + "community_name": "SKILL.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "reference.md", + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_claude_md_snippet", + "label": "CLAUDE_MD_SNIPPET.md", + "_origin": "ast", + "community": 73, + "community_name": "SKILL.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "claude_md_snippet.md", + "source_file": "skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_claude_md_snippet_session_continuity", + "label": "Session continuity", + "_origin": "ast", + "community": 73, + "community_name": "SKILL.md", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session continuity", + "source_file": "skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md", + "source_location": "L8" + }, + { + "id": "skills_session_continuity_templates_learnings", + "label": "templates/LEARNINGS.md", + "_origin": "ast", + "community": 73, + "community_name": "SKILL.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "templates/learnings.md", + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_project_context", + "label": "templates/PROJECT_CONTEXT.md", + "_origin": "ast", + "community": 73, + "community_name": "SKILL.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "templates/project_context.md", + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_session_primer", + "label": "templates/SESSION_PRIMER.md", + "_origin": "ast", + "community": 74, + "community_name": "Session Primer \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "page", + "norm_label": "templates/session_primer.md", + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_session_primer_boot_order", + "label": "Boot order", + "_origin": "ast", + "community": 74, + "community_name": "Session Primer \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "boot order", + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L3" + }, + { + "id": "skills_session_continuity_templates_session_primer_confirm", + "label": "Confirm", + "_origin": "ast", + "community": 74, + "community_name": "Session Primer \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "confirm", + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L14" + }, + { + "id": "skills_session_continuity_templates_session_primer_mid_flight", + "label": "Mid-flight", + "_origin": "ast", + "community": 74, + "community_name": "Session Primer \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "mid-flight", + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L11" + }, + { + "id": "skills_session_continuity_templates_session_primer_peers", + "label": "Peers", + "_origin": "ast", + "community": 74, + "community_name": "Session Primer \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "peers", + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L19" + }, + { + "id": "skills_session_continuity_templates_session_primer_session_primer_project_name", + "label": "Session Primer \u2014 {{PROJECT_NAME}}", + "_origin": "ast", + "community": 74, + "community_name": "Session Primer \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session primer \u2014 {{project_name}}", + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L1" + }, + { + "id": "commands_doctor", + "label": "doctor.md", + "_origin": "ast", + "community": 75, + "community_name": "/session-continuity:doctor", + "file_type": "document", + "frontmatter": { + "description": "Diagnose whether session-continuity is actually wired up in this project \u2014 hooks registered, four in-repo files present and not stale, GitHub backlog reachable, plugin root resolves and isn't a stale cache, gate scripts executable. Zero args, read-only." + }, + "node_kind": "page", + "norm_label": "doctor.md", + "source_file": "commands/doctor.md", + "source_location": "L1" + }, + { + "id": "commands_doctor_notes", + "label": "Notes", + "_origin": "ast", + "community": 75, + "community_name": "/session-continuity:doctor", + "file_type": "document", + "node_kind": "heading", + "norm_label": "notes", + "source_file": "commands/doctor.md", + "source_location": "L137" + }, + { + "id": "commands_doctor_session_continuity_doctor", + "label": "/session-continuity:doctor", + "_origin": "ast", + "community": 75, + "community_name": "/session-continuity:doctor", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:doctor", + "source_file": "commands/doctor.md", + "source_location": "L5" + }, + { + "id": "commands_doctor_step_1_gather", + "label": "Step 1 \u2014 Gather", + "_origin": "ast", + "community": 75, + "community_name": "/session-continuity:doctor", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 1 \u2014 gather", + "source_file": "commands/doctor.md", + "source_location": "L11" + }, + { + "id": "commands_doctor_step_2_interpret_and_report", + "label": "Step 2 \u2014 Interpret and report", + "_origin": "ast", + "community": 75, + "community_name": "/session-continuity:doctor", + "file_type": "document", + "node_kind": "heading", + "norm_label": "step 2 \u2014 interpret and report", + "source_file": "commands/doctor.md", + "source_location": "L101" + }, + { + "id": "hooks_flaky_gate", + "label": "flaky-gate.sh", + "_origin": "ast", + "community": 76, + "community_name": "flaky-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "flaky-gate.sh", + "source_file": "hooks/flaky-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_flaky_gate_gate_check", + "label": "gate_check()", + "_origin": "ast", + "community": 76, + "community_name": "flaky-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check()", + "source_file": "hooks/flaky-gate.sh", + "source_location": "L17" + }, + { + "id": "hooks_flaky_gate_gate_check_file", + "label": "gate_check_file()", + "_origin": "ast", + "community": 76, + "community_name": "flaky-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check_file()", + "source_file": "hooks/flaky-gate.sh", + "source_location": "L31" + }, + { + "id": "hooks_flaky_gate_gate_in_scope", + "label": "gate_in_scope()", + "_origin": "ast", + "community": 76, + "community_name": "flaky-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_in_scope()", + "source_file": "hooks/flaky-gate.sh", + "source_location": "L12" + }, + { + "id": "hooks_flaky_gate_sh__entry", + "label": "flaky-gate.sh script", + "_origin": "ast", + "community": 76, + "community_name": "flaky-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "flaky-gate.sh script", + "source_file": "hooks/flaky-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_perf_log", + "label": "perf-log.sh", + "_origin": "ast", + "community": 77, + "community_name": "perf-log.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "perf-log.sh", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_perf_log_json_escape", + "label": "json_escape()", + "_origin": "ast", + "community": 77, + "community_name": "perf-log.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "json_escape()", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L34" + }, + { + "id": "hooks_lib_perf_log_resolve_mark_epoch", + "label": "resolve_mark_epoch()", + "_origin": "ast", + "community": 77, + "community_name": "perf-log.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "resolve_mark_epoch()", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L85" + }, + { + "id": "hooks_lib_perf_log_sh__entry", + "label": "perf-log.sh script", + "_origin": "ast", + "community": 77, + "community_name": "perf-log.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "perf-log.sh script", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_perf_log_write_record", + "label": "write_record()", + "_origin": "ast", + "community": 77, + "community_name": "perf-log.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "write_record()", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L42" + }, + { + "id": "hooks_lib_test_count_rerun", + "label": "test-count-rerun.sh", + "_origin": "ast", + "community": 78, + "community_name": "test-count-rerun.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "test-count-rerun.sh", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_test_count_rerun_die", + "label": "die()", + "_origin": "ast", + "community": 78, + "community_name": "test-count-rerun.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "die()", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L28" + }, + { + "id": "hooks_lib_test_count_rerun_run_once", + "label": "run_once()", + "_origin": "ast", + "community": 78, + "community_name": "test-count-rerun.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "run_once()", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L98" + }, + { + "id": "hooks_lib_test_count_rerun_sh__entry", + "label": "test-count-rerun.sh script", + "_origin": "ast", + "community": 78, + "community_name": "test-count-rerun.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "test-count-rerun.sh script", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_test_count_rerun_to_json", + "label": "to_json()", + "_origin": "ast", + "community": 78, + "community_name": "test-count-rerun.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "to_json()", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L120" + }, + { + "id": "security", + "label": "SECURITY.md", + "_origin": "ast", + "community": 79, + "community_name": "Security policy", + "file_type": "document", + "node_kind": "page", + "norm_label": "security.md", + "source_file": "SECURITY.md", + "source_location": "L1" + }, + { + "id": "security_design_notes_relevant_to_security_reviewers", + "label": "Design notes relevant to security reviewers", + "_origin": "ast", + "community": 79, + "community_name": "Security policy", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design notes relevant to security reviewers", + "source_file": "SECURITY.md", + "source_location": "L34" + }, + { + "id": "security_reporting", + "label": "Reporting", + "_origin": "ast", + "community": 79, + "community_name": "Security policy", + "file_type": "document", + "node_kind": "heading", + "norm_label": "reporting", + "source_file": "SECURITY.md", + "source_location": "L20" + }, + { + "id": "security_scope", + "label": "Scope", + "_origin": "ast", + "community": 79, + "community_name": "Security policy", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scope", + "source_file": "SECURITY.md", + "source_location": "L5" + }, + { + "id": "security_security_policy", + "label": "Security policy", + "_origin": "ast", + "community": 79, + "community_name": "Security policy", + "file_type": "document", + "node_kind": "heading", + "norm_label": "security policy", + "source_file": "SECURITY.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design", + "label": "2026-06-17-occurrence-counter-and-spike-check-design.md", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "label": "Deliverable #2 \u2014 occurrence-gate hook", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "deliverable #2 \u2014 occurrence-gate hook", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L36" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_3c_spike_check_command", + "label": "Deliverable #3c \u2014 /spike-check command", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "deliverable #3c \u2014 /spike-check command", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L180" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_detection_rule", + "label": "Detection rule", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "detection rule", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L52" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_escape_hatch_explicit_skip_with_reason", + "label": "Escape hatch (explicit skip-with-reason)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "escape hatch (explicit skip-with-reason)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L72" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_form", + "label": "Form", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "form", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L199" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_front_matter_registration", + "label": "Front-matter & registration", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "front-matter & registration", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L229" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_learning_command_extension", + "label": "`/learning` command extension", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/learning` command extension", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L84" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_mechanics_reuse_proven_gate_sh_skeleton", + "label": "Mechanics (reuse proven-gate.sh skeleton)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "mechanics (reuse proven-gate.sh skeleton)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L107" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "label": "Occurrence-counter gate + spike-check command \u2014 change-the-odds #2 + #3c", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "occurrence-counter gate + spike-check command \u2014 change-the-odds #2 + #3c", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_out_of_scope", + "label": "Out of scope", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "out of scope", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L270" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_scope_decided", + "label": "Scope (decided)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "scope (decided)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L44" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_self_reference_trap_learnings_7_1", + "label": "Self-reference trap (LEARNINGS #7 + #1)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "self-reference trap (learnings #7 + #1)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L149" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_success_criteria_the_invariants_for_this_workstream", + "label": "Success criteria (the invariants for this workstream)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "success criteria (the invariants for this workstream)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L261" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L241" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_testing_hermetic_no_containers", + "label": "Testing (hermetic, no containers)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing (hermetic, no containers)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L157" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_the_two_problems", + "label": "The two problems", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the two problems", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L16" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_versioning_ship", + "label": "Versioning / ship", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "versioning / ship", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L251" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_what_it_does_one_sentence", + "label": "What it does (one sentence)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what it does (one sentence)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L38" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_what_it_does_one_sentence_182", + "label": "What it does (one sentence)", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "what it does (one sentence)", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L182" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_why_a_command_not_a_hook", + "label": "Why a command, not a hook", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "why a command, not a hook", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L189" + }, + { + "id": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_wiring", + "label": "Wiring", + "_origin": "ast", + "community": 8, + "community_name": "Deliverable #2 \u2014 occurrence-gate hook", + "file_type": "document", + "node_kind": "heading", + "norm_label": "wiring", + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L136" + }, + { + "id": "session_continuity_roadmap", + "label": ".session-continuity/ROADMAP.md", + "_origin": "ast", + "community": 80, + "community_name": "Roadmap \u2014 session-continuity", + "file_type": "document", + "node_kind": "page", + "norm_label": ".session-continuity/roadmap.md", + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L1" + }, + { + "id": "session_continuity_roadmap_later", + "label": "Later", + "_origin": "ast", + "community": 80, + "community_name": "Roadmap \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "later", + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L38" + }, + { + "id": "session_continuity_roadmap_next", + "label": "Next", + "_origin": "ast", + "community": 80, + "community_name": "Roadmap \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "next", + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L29" + }, + { + "id": "session_continuity_roadmap_now", + "label": "Now", + "_origin": "ast", + "community": 80, + "community_name": "Roadmap \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "now", + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L9" + }, + { + "id": "session_continuity_roadmap_roadmap_session_continuity", + "label": "Roadmap \u2014 session-continuity", + "_origin": "ast", + "community": 80, + "community_name": "Roadmap \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "roadmap \u2014 session-continuity", + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_roadmap", + "label": "templates/ROADMAP.md", + "_origin": "ast", + "community": 81, + "community_name": "Roadmap \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "page", + "norm_label": "templates/roadmap.md", + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L1" + }, + { + "id": "skills_session_continuity_templates_roadmap_later", + "label": "Later", + "_origin": "ast", + "community": 81, + "community_name": "Roadmap \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "later", + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L17" + }, + { + "id": "skills_session_continuity_templates_roadmap_next", + "label": "Next", + "_origin": "ast", + "community": 81, + "community_name": "Roadmap \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "next", + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L13" + }, + { + "id": "skills_session_continuity_templates_roadmap_now", + "label": "Now", + "_origin": "ast", + "community": 81, + "community_name": "Roadmap \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "now", + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L9" + }, + { + "id": "skills_session_continuity_templates_roadmap_roadmap_project_name", + "label": "Roadmap \u2014 {{PROJECT_NAME}}", + "_origin": "ast", + "community": 81, + "community_name": "Roadmap \u2014 {{PROJECT_NAME}}", + "file_type": "document", + "node_kind": "heading", + "norm_label": "roadmap \u2014 {{project_name}}", + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L1" + }, + { + "id": "changelog_0_17_0_2026_08_27", + "label": "[0.17.0] \u2014 2026-08-27", + "_origin": "ast", + "community": 82, + "community_name": "[0.17.0] \u2014 2026-08-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.17.0] \u2014 2026-08-27", + "source_file": "CHANGELOG.md", + "source_location": "L243" + }, + { + "id": "changelog_accepted_limitation", + "label": "Accepted limitation", + "_origin": "ast", + "community": 82, + "community_name": "[0.17.0] \u2014 2026-08-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "accepted limitation", + "source_file": "CHANGELOG.md", + "source_location": "L284" + }, + { + "id": "changelog_changed_245", + "label": "Changed", + "_origin": "ast", + "community": 82, + "community_name": "[0.17.0] \u2014 2026-08-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L245" + }, + { + "id": "changelog_fixed_269", + "label": "Fixed", + "_origin": "ast", + "community": 82, + "community_name": "[0.17.0] \u2014 2026-08-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L269" + }, + { + "id": "changelog_0_18_0_2026_08_30", + "label": "[0.18.0] \u2014 2026-08-30", + "_origin": "ast", + "community": 83, + "community_name": "[0.18.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.18.0] \u2014 2026-08-30", + "source_file": "CHANGELOG.md", + "source_location": "L185" + }, + { + "id": "changelog_added_187", + "label": "Added", + "_origin": "ast", + "community": 83, + "community_name": "[0.18.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L187" + }, + { + "id": "changelog_changed_220", + "label": "Changed", + "_origin": "ast", + "community": 83, + "community_name": "[0.18.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L220" + }, + { + "id": "changelog_fixed_232", + "label": "Fixed", + "_origin": "ast", + "community": 83, + "community_name": "[0.18.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L232" + }, + { + "id": "changelog_0_19_0_2026_08_30", + "label": "[0.19.0] \u2014 2026-08-30", + "_origin": "ast", + "community": 84, + "community_name": "[0.19.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.19.0] \u2014 2026-08-30", + "source_file": "CHANGELOG.md", + "source_location": "L171" + }, + { + "id": "changelog_added_173", + "label": "Added", + "_origin": "ast", + "community": 84, + "community_name": "[0.19.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L173" + }, + { + "id": "changelog_changed_181", + "label": "Changed", + "_origin": "ast", + "community": 84, + "community_name": "[0.19.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L181" + }, + { + "id": "changelog_fixed_177", + "label": "Fixed", + "_origin": "ast", + "community": 84, + "community_name": "[0.19.0] \u2014 2026-08-30", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L177" + }, + { + "id": "changelog_0_29_0_2026_09_07", + "label": "[0.29.0] \u2014 2026-09-07", + "_origin": "ast", + "community": 85, + "community_name": "[0.29.0] \u2014 2026-09-07", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.29.0] \u2014 2026-09-07", + "source_file": "CHANGELOG.md", + "source_location": "L63" + }, + { + "id": "changelog_changed_65", + "label": "Changed", + "_origin": "ast", + "community": 85, + "community_name": "[0.29.0] \u2014 2026-09-07", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L65" + }, + { + "id": "changelog_migration", + "label": "Migration", + "_origin": "ast", + "community": 85, + "community_name": "[0.29.0] \u2014 2026-09-07", + "file_type": "document", + "node_kind": "heading", + "norm_label": "migration", + "source_file": "CHANGELOG.md", + "source_location": "L73" + }, + { + "id": "changelog_removed", + "label": "Removed", + "_origin": "ast", + "community": 85, + "community_name": "[0.29.0] \u2014 2026-09-07", + "file_type": "document", + "node_kind": "heading", + "norm_label": "removed", + "source_file": "CHANGELOG.md", + "source_location": "L70" + }, + { + "id": "changelog_0_2_0_2026_04_27", + "label": "[0.2.0] \u2014 2026-04-27", + "_origin": "ast", + "community": 86, + "community_name": "[0.2.0] \u2014 2026-04-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.2.0] \u2014 2026-04-27", + "source_file": "CHANGELOG.md", + "source_location": "L719" + }, + { + "id": "changelog_added_721", + "label": "Added", + "_origin": "ast", + "community": 86, + "community_name": "[0.2.0] \u2014 2026-04-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L721" + }, + { + "id": "changelog_changed_730", + "label": "Changed", + "_origin": "ast", + "community": 86, + "community_name": "[0.2.0] \u2014 2026-04-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L730" + }, + { + "id": "changelog_removed_736", + "label": "Removed", + "_origin": "ast", + "community": 86, + "community_name": "[0.2.0] \u2014 2026-04-27", + "file_type": "document", + "node_kind": "heading", + "norm_label": "removed", + "source_file": "CHANGELOG.md", + "source_location": "L736" + }, + { + "id": "changelog_0_4_0_2026_04_28", + "label": "[0.4.0] \u2014 2026-04-28", + "_origin": "ast", + "community": 87, + "community_name": "[0.4.0] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.4.0] \u2014 2026-04-28", + "source_file": "CHANGELOG.md", + "source_location": "L689" + }, + { + "id": "changelog_added_691", + "label": "Added", + "_origin": "ast", + "community": 87, + "community_name": "[0.4.0] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L691" + }, + { + "id": "changelog_changed_696", + "label": "Changed", + "_origin": "ast", + "community": 87, + "community_name": "[0.4.0] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L696" + }, + { + "id": "changelog_fixed_706", + "label": "Fixed", + "_origin": "ast", + "community": 87, + "community_name": "[0.4.0] \u2014 2026-04-28", + "file_type": "document", + "node_kind": "heading", + "norm_label": "fixed", + "source_file": "CHANGELOG.md", + "source_location": "L706" + }, + { + "id": "changelog_0_6_0_2026_05_21", + "label": "[0.6.0] \u2014 2026-05-21", + "_origin": "ast", + "community": 88, + "community_name": "[0.6.0] \u2014 2026-05-21", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.6.0] \u2014 2026-05-21", + "source_file": "CHANGELOG.md", + "source_location": "L634" + }, + { + "id": "changelog_added_636", + "label": "Added", + "_origin": "ast", + "community": 88, + "community_name": "[0.6.0] \u2014 2026-05-21", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L636" + }, + { + "id": "changelog_changed_645", + "label": "Changed", + "_origin": "ast", + "community": 88, + "community_name": "[0.6.0] \u2014 2026-05-21", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L645" + }, + { + "id": "changelog_compatibility_649", + "label": "Compatibility", + "_origin": "ast", + "community": 88, + "community_name": "[0.6.0] \u2014 2026-05-21", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L649" + }, + { + "id": "changelog_0_7_0_2026_05_23", + "label": "[0.7.0] \u2014 2026-05-23", + "_origin": "ast", + "community": 89, + "community_name": "[0.7.0] \u2014 2026-05-23", + "file_type": "document", + "node_kind": "heading", + "norm_label": "[0.7.0] \u2014 2026-05-23", + "source_file": "CHANGELOG.md", + "source_location": "L621" + }, + { + "id": "changelog_added_628", + "label": "Added", + "_origin": "ast", + "community": 89, + "community_name": "[0.7.0] \u2014 2026-05-23", + "file_type": "document", + "node_kind": "heading", + "norm_label": "added", + "source_file": "CHANGELOG.md", + "source_location": "L628" + }, + { + "id": "changelog_changed_623", + "label": "Changed", + "_origin": "ast", + "community": 89, + "community_name": "[0.7.0] \u2014 2026-05-23", + "file_type": "document", + "node_kind": "heading", + "norm_label": "changed", + "source_file": "CHANGELOG.md", + "source_location": "L623" + }, + { + "id": "changelog_compatibility_631", + "label": "Compatibility", + "_origin": "ast", + "community": 89, + "community_name": "[0.7.0] \u2014 2026-05-23", + "file_type": "document", + "node_kind": "heading", + "norm_label": "compatibility", + "source_file": "CHANGELOG.md", + "source_location": "L631" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design", + "label": "2026-09-09-primer-thin-hard-template-design.md", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-09-09-primer-thin-hard-template-design.md", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_content_contract", + "label": "Content contract", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "content contract", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L127" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_decisions", + "label": "Decisions", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "decisions", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L67" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "label": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design: thin hard-template session_primer.md (engrim + graphify required)", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_doctor", + "label": "Doctor", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "doctor", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L224" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_goals", + "label": "Goals", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "goals", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L34" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_migration", + "label": "Migration", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "migration", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L267" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_new_helper_hooks_lib_peer_probes_sh", + "label": "New helper: `hooks/lib/peer-probes.sh`", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "new helper: `hooks/lib/peer-probes.sh`", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L175" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_new_helper_hooks_lib_primer_validate_sh", + "label": "New helper: `hooks/lib/primer-validate.sh`", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "new helper: `hooks/lib/primer-validate.sh`", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L194" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_non_goals", + "label": "Non-goals", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "non-goals", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L54" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_open_implementation_choices_plan_not_design", + "label": "Open implementation choices (plan, not design)", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "open implementation choices (plan, not design)", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L308" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_pre_commit_nudge", + "label": "Pre-commit nudge", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "pre-commit nudge", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L255" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_privacy_product_copy", + "label": "Privacy / product copy", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "privacy / product copy", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L300" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_problem", + "label": "Problem", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "problem", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L7" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "label": "Runtime", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "runtime", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L173" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_section_rules", + "label": "Section rules", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "section rules", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L157" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_session_continuity_end_session", + "label": "`/session-continuity:end-session`", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:end-session`", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L260" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_session_continuity_primer", + "label": "`/session-continuity:primer`", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "`/session-continuity:primer`", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L236" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_sessionstart_hooks_session_start_sh", + "label": "SessionStart (`hooks/session-start.sh`)", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "sessionstart (`hooks/session-start.sh`)", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L207" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_success_criteria", + "label": "Success criteria", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "success criteria", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L323" + }, + { + "id": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_testing", + "label": "Testing", + "_origin": "ast", + "community": 9, + "community_name": "Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required)", + "file_type": "document", + "node_kind": "heading", + "norm_label": "testing", + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L280" + }, + { + "id": "commands_spike_check", + "label": "spike-check.md", + "_origin": "ast", + "community": 90, + "community_name": "/session-continuity:spike-check $ARGUMENTS", + "file_type": "document", + "frontmatter": { + "description": "Emit the stand-in spike checklist BEFORE a spike, so it's designed to hit the real binary + auth/lifecycle/fixed-port path (change-the-odds #3c)." + }, + "node_kind": "page", + "norm_label": "spike-check.md", + "source_file": "commands/spike-check.md", + "source_location": "L1" + }, + { + "id": "commands_spike_check_closing", + "label": "Closing", + "_origin": "ast", + "community": 90, + "community_name": "/session-continuity:spike-check $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "closing", + "source_file": "commands/spike-check.md", + "source_location": "L27" + }, + { + "id": "commands_spike_check_session_continuity_spike_check_arguments", + "label": "/session-continuity:spike-check $ARGUMENTS", + "_origin": "ast", + "community": 90, + "community_name": "/session-continuity:spike-check $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "/session-continuity:spike-check $arguments", + "source_file": "commands/spike-check.md", + "source_location": "L5" + }, + { + "id": "commands_spike_check_the_stand_in_spike_checklist", + "label": "The stand-in spike checklist", + "_origin": "ast", + "community": 90, + "community_name": "/session-continuity:spike-check $ARGUMENTS", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the stand-in spike checklist", + "source_file": "commands/spike-check.md", + "source_location": "L15" + }, + { + "id": "hooks_backend_parity_gate", + "label": "backend-parity-gate.sh", + "_origin": "ast", + "community": 91, + "community_name": "backend-parity-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "backend-parity-gate.sh", + "source_file": "hooks/backend-parity-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_backend_parity_gate_gate_check", + "label": "gate_check()", + "_origin": "ast", + "community": 91, + "community_name": "backend-parity-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check()", + "source_file": "hooks/backend-parity-gate.sh", + "source_location": "L18" + }, + { + "id": "hooks_backend_parity_gate_gate_in_scope", + "label": "gate_in_scope()", + "_origin": "ast", + "community": 91, + "community_name": "backend-parity-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_in_scope()", + "source_file": "hooks/backend-parity-gate.sh", + "source_location": "L11" + }, + { + "id": "hooks_backend_parity_gate_sh__entry", + "label": "backend-parity-gate.sh script", + "_origin": "ast", + "community": 91, + "community_name": "backend-parity-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "backend-parity-gate.sh script", + "source_file": "hooks/backend-parity-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_evidence_gate", + "label": "evidence-gate.sh", + "_origin": "ast", + "community": 92, + "community_name": "evidence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "evidence-gate.sh", + "source_file": "hooks/evidence-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_evidence_gate_gate_check", + "label": "gate_check()", + "_origin": "ast", + "community": 92, + "community_name": "evidence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check()", + "source_file": "hooks/evidence-gate.sh", + "source_location": "L18" + }, + { + "id": "hooks_evidence_gate_gate_in_scope", + "label": "gate_in_scope()", + "_origin": "ast", + "community": 92, + "community_name": "evidence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_in_scope()", + "source_file": "hooks/evidence-gate.sh", + "source_location": "L12" + }, + { + "id": "hooks_evidence_gate_sh__entry", + "label": "evidence-gate.sh script", + "_origin": "ast", + "community": 92, + "community_name": "evidence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "evidence-gate.sh script", + "source_file": "hooks/evidence-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_detect", + "label": "primer-detect.sh", + "_origin": "ast", + "community": 93, + "community_name": "primer-detect.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "primer-detect.sh", + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L1" + }, + { + "id": "hooks_lib_primer_detect_die", + "label": "die()", + "_origin": "ast", + "community": 93, + "community_name": "primer-detect.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "die()", + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L35" + }, + { + "id": "hooks_lib_primer_detect_file_flag", + "label": "file_flag()", + "_origin": "ast", + "community": 93, + "community_name": "primer-detect.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "file_flag()", + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L49" + }, + { + "id": "hooks_lib_primer_detect_sh__entry", + "label": "primer-detect.sh script", + "_origin": "ast", + "community": 93, + "community_name": "primer-detect.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "primer-detect.sh script", + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L1" + }, + { + "id": "hooks_occurrence_gate", + "label": "occurrence-gate.sh", + "_origin": "ast", + "community": 94, + "community_name": "occurrence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "occurrence-gate.sh", + "source_file": "hooks/occurrence-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_occurrence_gate_gate_check", + "label": "gate_check()", + "_origin": "ast", + "community": 94, + "community_name": "occurrence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check()", + "source_file": "hooks/occurrence-gate.sh", + "source_location": "L18" + }, + { + "id": "hooks_occurrence_gate_gate_in_scope", + "label": "gate_in_scope()", + "_origin": "ast", + "community": 94, + "community_name": "occurrence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_in_scope()", + "source_file": "hooks/occurrence-gate.sh", + "source_location": "L12" + }, + { + "id": "hooks_occurrence_gate_sh__entry", + "label": "occurrence-gate.sh script", + "_origin": "ast", + "community": 94, + "community_name": "occurrence-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "occurrence-gate.sh script", + "source_file": "hooks/occurrence-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_proven_gate", + "label": "proven-gate.sh", + "_origin": "ast", + "community": 95, + "community_name": "proven-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "proven-gate.sh", + "source_file": "hooks/proven-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_proven_gate_gate_check", + "label": "gate_check()", + "_origin": "ast", + "community": 95, + "community_name": "proven-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check()", + "source_file": "hooks/proven-gate.sh", + "source_location": "L22" + }, + { + "id": "hooks_proven_gate_gate_in_scope", + "label": "gate_in_scope()", + "_origin": "ast", + "community": 95, + "community_name": "proven-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_in_scope()", + "source_file": "hooks/proven-gate.sh", + "source_location": "L16" + }, + { + "id": "hooks_proven_gate_sh__entry", + "label": "proven-gate.sh script", + "_origin": "ast", + "community": 95, + "community_name": "proven-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "proven-gate.sh script", + "source_file": "hooks/proven-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_smoke_gate", + "label": "smoke-gate.sh", + "_origin": "ast", + "community": 96, + "community_name": "smoke-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "file" + }, + "norm_label": "smoke-gate.sh", + "source_file": "hooks/smoke-gate.sh", + "source_location": "L1" + }, + { + "id": "hooks_smoke_gate_gate_check", + "label": "gate_check()", + "_origin": "ast", + "community": 96, + "community_name": "smoke-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_check()", + "source_file": "hooks/smoke-gate.sh", + "source_location": "L18" + }, + { + "id": "hooks_smoke_gate_gate_in_scope", + "label": "gate_in_scope()", + "_origin": "ast", + "community": 96, + "community_name": "smoke-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "norm_label": "gate_in_scope()", + "source_file": "hooks/smoke-gate.sh", + "source_location": "L11" + }, + { + "id": "hooks_smoke_gate_sh__entry", + "label": "smoke-gate.sh script", + "_origin": "ast", + "community": 96, + "community_name": "smoke-gate.sh", + "file_type": "code", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "norm_label": "smoke-gate.sh script", + "source_file": "hooks/smoke-gate.sh", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items", + "label": "2026-08-12-session-start-outstanding-items.md", + "_origin": "ast", + "community": 97, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "page", + "norm_label": "2026-08-12-session-start-outstanding-items.md", + "source_file": "meta/superpowers/plans/2026-08-12-session-start-outstanding-items.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_global_constraints", + "label": "Global Constraints", + "_origin": "ast", + "community": 97, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "global constraints", + "source_file": "meta/superpowers/plans/2026-08-12-session-start-outstanding-items.md", + "source_location": "L11" + }, + { + "id": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_sessionstart_outstanding_items_surfacing_implementation_plan", + "label": "SessionStart Outstanding-Items Surfacing Implementation Plan", + "_origin": "ast", + "community": 97, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "sessionstart outstanding-items surfacing implementation plan", + "source_file": "meta/superpowers/plans/2026-08-12-session-start-outstanding-items.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_task_1_extract_and_surface_outstanding_items_in_hooks_session_start_sh", + "label": "Task 1: Extract and surface outstanding items in `hooks/session-start.sh`", + "_origin": "ast", + "community": 97, + "community_name": "Global Constraints", + "file_type": "document", + "node_kind": "heading", + "norm_label": "task 1: extract and surface outstanding items in `hooks/session-start.sh`", + "source_file": "meta/superpowers/plans/2026-08-12-session-start-outstanding-items.md", + "source_location": "L22" + }, + { + "id": "meta_superpowers_recommendations_docguard_design_sketch", + "label": "docguard-design-sketch.md", + "_origin": "ast", + "community": 98, + "community_name": "Design sketch: generalized docs-current gate", + "file_type": "document", + "node_kind": "page", + "norm_label": "docguard-design-sketch.md", + "source_file": "meta/superpowers/recommendations/docguard-design-sketch.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_recommendations_docguard_design_sketch_design_sketch_generalized_docs_current_gate", + "label": "Design sketch: generalized docs-current gate", + "_origin": "ast", + "community": 98, + "community_name": "Design sketch: generalized docs-current gate", + "file_type": "document", + "node_kind": "heading", + "norm_label": "design sketch: generalized docs-current gate", + "source_file": "meta/superpowers/recommendations/docguard-design-sketch.md", + "source_location": "L1" + }, + { + "id": "meta_superpowers_recommendations_docguard_design_sketch_implemented_2026_09_08", + "label": "Implemented (2026-09-08)", + "_origin": "ast", + "community": 98, + "community_name": "Design sketch: generalized docs-current gate", + "file_type": "document", + "node_kind": "heading", + "norm_label": "implemented (2026-09-08)", + "source_file": "meta/superpowers/recommendations/docguard-design-sketch.md", + "source_location": "L23" + }, + { + "id": "meta_superpowers_recommendations_docguard_design_sketch_the_gap", + "label": "The gap", + "_origin": "ast", + "community": 98, + "community_name": "Design sketch: generalized docs-current gate", + "file_type": "document", + "node_kind": "heading", + "norm_label": "the gap", + "source_file": "meta/superpowers/recommendations/docguard-design-sketch.md", + "source_location": "L7" + }, + { + "id": "session_continuity_session_primer", + "label": ".session-continuity/SESSION_PRIMER.md", + "_origin": "ast", + "community": 99, + "community_name": "Session Primer \u2014 session-continuity", + "file_type": "document", + "node_kind": "page", + "norm_label": ".session-continuity/session_primer.md", + "source_file": ".session-continuity/SESSION_PRIMER.md", + "source_location": "L1" + }, + { + "id": "session_continuity_session_primer_current_state", + "label": "Current state", + "_origin": "ast", + "community": 99, + "community_name": "Session Primer \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "current state", + "source_file": ".session-continuity/SESSION_PRIMER.md", + "source_location": "L21" + }, + { + "id": "session_continuity_session_primer_first_things_first_read_these_before_touching_anything", + "label": "First things first (read these before touching anything)", + "_origin": "ast", + "community": 99, + "community_name": "Session Primer \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "first things first (read these before touching anything)", + "source_file": ".session-continuity/SESSION_PRIMER.md", + "source_location": "L9" + }, + { + "id": "session_continuity_session_primer_session_primer_session_continuity", + "label": "Session Primer \u2014 session-continuity", + "_origin": "ast", + "community": 99, + "community_name": "Session Primer \u2014 session-continuity", + "file_type": "document", + "node_kind": "heading", + "norm_label": "session primer \u2014 session-continuity", + "source_file": ".session-continuity/SESSION_PRIMER.md", + "source_location": "L1" + } + ], + "links": [ + { + "source": "hooks_derived_value_gate_dvg_check_compare", + "target": "hooks_derived_value_gate_dvg_deny", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L59", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate_dvg_check_count", + "target": "hooks_derived_value_gate_dvg_deny", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L51", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate_dvg_check_duration", + "target": "hooks_derived_value_gate_dvg_deny", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L43", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate_dvg_check_verbatim", + "target": "hooks_derived_value_gate_dvg_deny", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate_gate_check", + "target": "hooks_derived_value_gate_dvg_check_duration", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L81", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate_gate_check", + "target": "hooks_derived_value_gate_dvg_check_count", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L82", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate_gate_check", + "target": "hooks_derived_value_gate_dvg_check_compare", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L83", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate_gate_check", + "target": "hooks_derived_value_gate_dvg_check_verbatim", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L84", + "weight": 1.0 + }, + { + "source": "hooks_flaky_gate_gate_check_file", + "target": "hooks_flaky_gate_gate_check", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/flaky-gate.sh", + "source_location": "L31", + "weight": 1.0 + }, + { + "source": "hooks_flaky_gate_sh__entry", + "target": "hooks_flaky_gate_gate_check", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/flaky-gate.sh", + "source_location": "L36", + "weight": 1.0 + }, + { + "source": "hooks_lib_backlog_issues_sh__entry", + "target": "hooks_lib_backlog_issues_fail_open", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/backlog-issues.sh", + "source_location": "L48", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract_emit", + "target": "hooks_lib_candidate_extract_finish", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract_sh__entry", + "target": "hooks_lib_candidate_extract_finish", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L100", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract_sh__entry", + "target": "hooks_lib_candidate_extract_emit", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L68", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract_sh__entry", + "target": "hooks_lib_candidate_extract_mtime_epoch", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L79", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_render_sh__entry", + "target": "hooks_lib_candidate_render_fallback", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/candidate-render.sh", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "hooks_lib_checklist_assemble_sh__entry", + "target": "hooks_lib_checklist_assemble_fallback", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/checklist-assemble.sh", + "source_location": "L29", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common_gate_load", + "target": "hooks_lib_gate_common_gate_field", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common_gate_load", + "target": "hooks_lib_gate_common_gate_command", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common_gate_scan_staged", + "target": "hooks_lib_gate_common_gate_is_scratch", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L112", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common_gate_scan_staged", + "target": "hooks_lib_gate_common_gate_staged_blob", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L113", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_check_siblings", + "target": "hooks_lib_learnings_index_die_install", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_reindex", + "target": "hooks_lib_learnings_index_check_siblings", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L69", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_reindex", + "target": "hooks_lib_learnings_index_die_install", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L71", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_reindex", + "target": "hooks_lib_learnings_index_count_entries", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L89", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_report", + "target": "hooks_lib_learnings_index_check_siblings", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L61", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_report", + "target": "hooks_lib_learnings_index_die_install", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_sh__entry", + "target": "hooks_lib_learnings_index_report", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L112", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index_sh__entry", + "target": "hooks_lib_learnings_index_reindex", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L113", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_log_sh__entry", + "target": "hooks_lib_perf_log_write_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L136", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_log_sh__entry", + "target": "hooks_lib_perf_log_resolve_mark_epoch", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L177", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_log_write_record", + "target": "hooks_lib_perf_log_json_escape", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L69", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_detect_sh__entry", + "target": "hooks_lib_primer_detect_die", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L41", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_detect_sh__entry", + "target": "hooks_lib_primer_detect_file_flag", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L53", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_init_derive_sh__entry", + "target": "hooks_lib_primer_init_derive_die", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/primer-init-derive.sh", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_check_sibling", + "target": "hooks_lib_render_die_install", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_render_backlog", + "target": "hooks_lib_render_check_sibling", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L46", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_render_backlog", + "target": "hooks_lib_render_die_install", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_render_learnings", + "target": "hooks_lib_render_check_sibling", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L57", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_render_learnings", + "target": "hooks_lib_render_die_install", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L65", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_sh__entry", + "target": "hooks_lib_render_render_backlog", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L144", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_sh__entry", + "target": "hooks_lib_render_render_learnings", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L147", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_sh__entry", + "target": "hooks_lib_render_render_help", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L149", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_sh__entry", + "target": "hooks_lib_render_render_update", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L150", + "weight": 1.0 + }, + { + "source": "hooks_lib_render_sh__entry", + "target": "hooks_lib_render_die_install", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/render.sh", + "source_location": "L152", + "weight": 1.0 + }, + { + "source": "hooks_lib_resolve_transcript_sh__entry", + "target": "hooks_lib_resolve_transcript_mtime_epoch", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/resolve-transcript.sh", + "source_location": "L45", + "weight": 1.0 + }, + { + "source": "hooks_lib_test_count_rerun_sh__entry", + "target": "hooks_lib_test_count_rerun_run_once", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L110", + "weight": 1.0 + }, + { + "source": "hooks_lib_test_count_rerun_sh__entry", + "target": "hooks_lib_test_count_rerun_to_json", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L121", + "weight": 1.0 + }, + { + "source": "hooks_lib_test_count_rerun_sh__entry", + "target": "hooks_lib_test_count_rerun_die", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "hooks_lib_token_overlap_sh__entry", + "target": "hooks_lib_token_overlap_die", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/lib/token-overlap.sh", + "source_location": "L40", + "weight": 1.0 + }, + { + "source": "hooks_version_check_sh__entry", + "target": "hooks_version_check_json_field", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "hooks/version-check.sh", + "source_location": "L100", + "weight": 1.0 + }, + { + "source": "changelog", + "target": "changelog_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "changelog_0_10_0_2026_06_17", + "target": "changelog_added_594", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L594", + "weight": 1.0 + }, + { + "source": "changelog_0_10_0_2026_06_17", + "target": "changelog_compatibility_599", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L599", + "weight": 1.0 + }, + { + "source": "changelog_0_11_0_2026_07_01", + "target": "changelog_added_584", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L584", + "weight": 1.0 + }, + { + "source": "changelog_0_11_0_2026_07_01", + "target": "changelog_compatibility_589", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L589", + "weight": 1.0 + }, + { + "source": "changelog_0_12_0_2026_07_30", + "target": "changelog_added_572", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L572", + "weight": 1.0 + }, + { + "source": "changelog_0_12_1_2026_08_06", + "target": "changelog_fixed_550", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L550", + "weight": 1.0 + }, + { + "source": "changelog_0_12_1_2026_08_06", + "target": "changelog_compatibility", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L565", + "weight": 1.0 + }, + { + "source": "changelog_0_12_2_2026_08_12", + "target": "changelog_fixed_528", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L528", + "weight": 1.0 + }, + { + "source": "changelog_0_12_2_2026_08_12", + "target": "changelog_added_542", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L542", + "weight": 1.0 + }, + { + "source": "changelog_0_12_3_2026_08_12", + "target": "changelog_added_509", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L509", + "weight": 1.0 + }, + { + "source": "changelog_0_12_3_2026_08_12", + "target": "changelog_fixed_517", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L517", + "weight": 1.0 + }, + { + "source": "changelog_0_13_0_2026_08_13", + "target": "changelog_added_490", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L490", + "weight": 1.0 + }, + { + "source": "changelog_0_14_0_2026_08_13", + "target": "changelog_removed_459", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L459", + "weight": 1.0 + }, + { + "source": "changelog_0_14_0_2026_08_13", + "target": "changelog_fixed_472", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L472", + "weight": 1.0 + }, + { + "source": "changelog_0_14_1_2026_08_13", + "target": "changelog_fixed_436", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L436", + "weight": 1.0 + }, + { + "source": "changelog_0_14_2_2026_08_14", + "target": "changelog_fixed_405", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L405", + "weight": 1.0 + }, + { + "source": "changelog_0_14_3_2026_08_14", + "target": "changelog_fixed_391", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L391", + "weight": 1.0 + }, + { + "source": "changelog_0_14_4_2026_08_15", + "target": "changelog_fixed_352", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L352", + "weight": 1.0 + }, + { + "source": "changelog_0_15_0_2026_08_17", + "target": "changelog_added_338", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L338", + "weight": 1.0 + }, + { + "source": "changelog_0_15_1_2026_08_17", + "target": "changelog_fixed_318", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L318", + "weight": 1.0 + }, + { + "source": "changelog_0_16_0_2026_08_22", + "target": "changelog_added_298", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L298", + "weight": 1.0 + }, + { + "source": "changelog_0_16_0_2026_08_22", + "target": "changelog_considered_and_dropped", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L308", + "weight": 1.0 + }, + { + "source": "changelog_0_17_0_2026_08_27", + "target": "changelog_changed_245", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L245", + "weight": 1.0 + }, + { + "source": "changelog_0_17_0_2026_08_27", + "target": "changelog_fixed_269", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L269", + "weight": 1.0 + }, + { + "source": "changelog_0_17_0_2026_08_27", + "target": "changelog_accepted_limitation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L284", + "weight": 1.0 + }, + { + "source": "changelog_0_18_0_2026_08_30", + "target": "changelog_added_187", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L187", + "weight": 1.0 + }, + { + "source": "changelog_0_18_0_2026_08_30", + "target": "changelog_changed_220", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L220", + "weight": 1.0 + }, + { + "source": "changelog_0_18_0_2026_08_30", + "target": "changelog_fixed_232", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L232", + "weight": 1.0 + }, + { + "source": "changelog_0_19_0_2026_08_30", + "target": "changelog_added_173", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L173", + "weight": 1.0 + }, + { + "source": "changelog_0_19_0_2026_08_30", + "target": "changelog_fixed_177", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L177", + "weight": 1.0 + }, + { + "source": "changelog_0_19_0_2026_08_30", + "target": "changelog_changed_181", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L181", + "weight": 1.0 + }, + { + "source": "changelog_0_20_0_2026_08_31", + "target": "changelog_added_168", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L168", + "weight": 1.0 + }, + { + "source": "changelog_0_21_0_2026_08_31", + "target": "changelog_added_160", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L160", + "weight": 1.0 + }, + { + "source": "changelog_0_21_0_2026_08_31", + "target": "changelog_fixed_163", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L163", + "weight": 1.0 + }, + { + "source": "changelog_0_21_1_2026_08_31", + "target": "changelog_fixed_155", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L155", + "weight": 1.0 + }, + { + "source": "changelog_0_22_0_2026_08_31", + "target": "changelog_added_146", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L146", + "weight": 1.0 + }, + { + "source": "changelog_0_22_0_2026_08_31", + "target": "changelog_changed_150", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L150", + "weight": 1.0 + }, + { + "source": "changelog_0_23_0_2026_09_01", + "target": "changelog_added_133", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L133", + "weight": 1.0 + }, + { + "source": "changelog_0_23_0_2026_09_01", + "target": "changelog_changed_139", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L139", + "weight": 1.0 + }, + { + "source": "changelog_0_24_0_2026_09_01", + "target": "changelog_changed_128", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L128", + "weight": 1.0 + }, + { + "source": "changelog_0_25_0_2026_09_01", + "target": "changelog_fixed_113", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L113", + "weight": 1.0 + }, + { + "source": "changelog_0_25_0_2026_09_01", + "target": "changelog_changed_122", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L122", + "weight": 1.0 + }, + { + "source": "changelog_0_25_1_2026_09_02", + "target": "changelog_fixed_108", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L108", + "weight": 1.0 + }, + { + "source": "changelog_0_25_2_2026_09_02", + "target": "changelog_fixed_102", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L102", + "weight": 1.0 + }, + { + "source": "changelog_0_26_0_2026_09_02", + "target": "changelog_added_95", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L95", + "weight": 1.0 + }, + { + "source": "changelog_0_27_0_2026_09_02", + "target": "changelog_changed_90", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L90", + "weight": 1.0 + }, + { + "source": "changelog_0_27_1_2026_09_04", + "target": "changelog_fixed_84", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L84", + "weight": 1.0 + }, + { + "source": "changelog_0_28_0_2026_09_03", + "target": "changelog_changed_78", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L78", + "weight": 1.0 + }, + { + "source": "changelog_0_29_0_2026_09_07", + "target": "changelog_changed_65", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L65", + "weight": 1.0 + }, + { + "source": "changelog_0_29_0_2026_09_07", + "target": "changelog_removed", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L70", + "weight": 1.0 + }, + { + "source": "changelog_0_29_0_2026_09_07", + "target": "changelog_migration", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L73", + "weight": 1.0 + }, + { + "source": "changelog_0_29_1_2026_09_07", + "target": "changelog_fixed_60", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L60", + "weight": 1.0 + }, + { + "source": "changelog_0_2_0_2026_04_27", + "target": "changelog_added_721", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L721", + "weight": 1.0 + }, + { + "source": "changelog_0_2_0_2026_04_27", + "target": "changelog_changed_730", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L730", + "weight": 1.0 + }, + { + "source": "changelog_0_2_0_2026_04_27", + "target": "changelog_removed_736", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L736", + "weight": 1.0 + }, + { + "source": "changelog_0_30_0_2026_09_08", + "target": "changelog_changed_55", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L55", + "weight": 1.0 + }, + { + "source": "changelog_0_31_0_2026_09_08", + "target": "changelog_changed_50", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L50", + "weight": 1.0 + }, + { + "source": "changelog_0_32_0_2026_09_08", + "target": "changelog_changed_45", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L45", + "weight": 1.0 + }, + { + "source": "changelog_0_33_0_2026_09_09", + "target": "changelog_changed_40", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L40", + "weight": 1.0 + }, + { + "source": "changelog_0_34_0_2026_09_09", + "target": "changelog_changed", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "changelog_0_35_0_2026_09_09", + "target": "changelog_fixed", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "changelog_0_35_0_2026_09_09", + "target": "changelog_added", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "changelog_0_3_0_2026_04_28", + "target": "changelog_added_712", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L712", + "weight": 1.0 + }, + { + "source": "changelog_0_3_0_2026_04_28", + "target": "changelog_changed_715", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L715", + "weight": 1.0 + }, + { + "source": "changelog_0_4_0_2026_04_28", + "target": "changelog_added_691", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L691", + "weight": 1.0 + }, + { + "source": "changelog_0_4_0_2026_04_28", + "target": "changelog_changed_696", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L696", + "weight": 1.0 + }, + { + "source": "changelog_0_4_0_2026_04_28", + "target": "changelog_fixed_706", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L706", + "weight": 1.0 + }, + { + "source": "changelog_0_4_1_2026_04_28", + "target": "changelog_fixed_682", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L682", + "weight": 1.0 + }, + { + "source": "changelog_0_4_1_2026_04_28", + "target": "changelog_changed_686", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L686", + "weight": 1.0 + }, + { + "source": "changelog_0_5_0_2026_05_12", + "target": "changelog_changed_670", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L670", + "weight": 1.0 + }, + { + "source": "changelog_0_5_0_2026_05_12", + "target": "changelog_compatibility_677", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L677", + "weight": 1.0 + }, + { + "source": "changelog_0_5_1_2026_05_21", + "target": "changelog_changed_654", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L654", + "weight": 1.0 + }, + { + "source": "changelog_0_5_1_2026_05_21", + "target": "changelog_compatibility_665", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L665", + "weight": 1.0 + }, + { + "source": "changelog_0_6_0_2026_05_21", + "target": "changelog_added_636", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L636", + "weight": 1.0 + }, + { + "source": "changelog_0_6_0_2026_05_21", + "target": "changelog_changed_645", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L645", + "weight": 1.0 + }, + { + "source": "changelog_0_6_0_2026_05_21", + "target": "changelog_compatibility_649", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L649", + "weight": 1.0 + }, + { + "source": "changelog_0_7_0_2026_05_23", + "target": "changelog_changed_623", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L623", + "weight": 1.0 + }, + { + "source": "changelog_0_7_0_2026_05_23", + "target": "changelog_added_628", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L628", + "weight": 1.0 + }, + { + "source": "changelog_0_7_0_2026_05_23", + "target": "changelog_compatibility_631", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L631", + "weight": 1.0 + }, + { + "source": "changelog_0_8_0_2026_06_15", + "target": "changelog_added_612", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L612", + "weight": 1.0 + }, + { + "source": "changelog_0_8_0_2026_06_15", + "target": "changelog_compatibility_618", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L618", + "weight": 1.0 + }, + { + "source": "changelog_0_9_0_2026_06_17", + "target": "changelog_added_604", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L604", + "weight": 1.0 + }, + { + "source": "changelog_0_9_0_2026_06_17", + "target": "changelog_compatibility_607", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L607", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_25_2_2026_09_02", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L100", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_25_1_2026_09_02", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L106", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_25_0_2026_09_01", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L111", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_24_0_2026_09_01", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L126", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_23_0_2026_09_01", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L131", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_22_0_2026_08_31", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L144", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_21_1_2026_08_31", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L153", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_21_0_2026_08_31", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L158", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_20_0_2026_08_31", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L166", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_19_0_2026_08_30", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L171", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_18_0_2026_08_30", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L185", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_34_0_2026_09_09", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L22", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_17_0_2026_08_27", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L243", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_16_0_2026_08_22", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L296", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_15_1_2026_08_17", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L316", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_15_0_2026_08_17", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L336", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_14_4_2026_08_15", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L350", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_33_0_2026_09_09", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_14_3_2026_08_14", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L389", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_14_2_2026_08_14", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L403", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_32_0_2026_09_08", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L43", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_14_1_2026_08_13", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L434", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_14_0_2026_08_13", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L457", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_31_0_2026_09_08", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L48", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_13_0_2026_08_13", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L488", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_35_0_2026_09_09", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_12_3_2026_08_12", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L507", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_12_2_2026_08_12", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L526", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_30_0_2026_09_08", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L53", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_12_1_2026_08_06", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L548", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_12_0_2026_07_30", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L570", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_29_1_2026_09_07", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L58", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_11_0_2026_07_01", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L582", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_10_0_2026_06_17", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L592", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_9_0_2026_06_17", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L602", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_8_0_2026_06_15", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L610", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_7_0_2026_05_23", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L621", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_29_0_2026_09_07", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_6_0_2026_05_21", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L634", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_5_1_2026_05_21", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L652", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_5_0_2026_05_12", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L668", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_4_1_2026_04_28", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L680", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_4_0_2026_04_28", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L689", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_3_0_2026_04_28", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L710", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_2_0_2026_04_27", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L719", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_1_0_2026_04_26", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L740", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_28_0_2026_09_03", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L76", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_27_1_2026_09_04", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L82", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_27_0_2026_09_02", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L88", + "weight": 1.0 + }, + { + "source": "changelog_changelog", + "target": "changelog_0_26_0_2026_09_02", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CHANGELOG.md", + "source_location": "L93", + "weight": 1.0 + }, + { + "source": "claude", + "target": "claude_project_conventions_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CLAUDE.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "claude_project_conventions_session_continuity", + "target": "claude_agent_meta_artifacts_go_under_meta_superpowers_not_docs", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CLAUDE.md", + "source_location": "L6", + "weight": 1.0 + }, + { + "source": "commands_backlog", + "target": "commands_backlog_session_continuity_backlog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/backlog.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_doctor", + "target": "commands_doctor_session_continuity_doctor", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/doctor.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_doctor_session_continuity_doctor", + "target": "commands_doctor_step_2_interpret_and_report", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/doctor.md", + "source_location": "L101", + "weight": 1.0 + }, + { + "source": "commands_doctor_session_continuity_doctor", + "target": "commands_doctor_step_1_gather", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/doctor.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "commands_doctor_session_continuity_doctor", + "target": "commands_doctor_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/doctor.md", + "source_location": "L137", + "weight": 1.0 + }, + { + "source": "commands_end_session", + "target": "commands_end_session_session_continuity_end_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_end_session_session_continuity_end_session", + "target": "commands_end_session_step_0_preconditions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "commands_end_session_session_continuity_end_session", + "target": "commands_end_session_step_1_refresh_the_primer_freshness_gated", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L26", + "weight": 1.0 + }, + { + "source": "commands_end_session_session_continuity_end_session", + "target": "commands_end_session_step_2_session_reflection_for_learnings", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L351", + "weight": 1.0 + }, + { + "source": "commands_end_session_session_continuity_end_session", + "target": "commands_end_session_step_3_final_checklist", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L473", + "weight": 1.0 + }, + { + "source": "commands_end_session_session_continuity_end_session", + "target": "commands_end_session_step_4_ritual_timing_always", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L562", + "weight": 1.0 + }, + { + "source": "commands_end_session_session_continuity_end_session", + "target": "commands_end_session_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L621", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_1_refresh_the_primer_freshness_gated", + "target": "commands_end_session_freshness_check_silent_no_user_prompt", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L214", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_1_refresh_the_primer_freshness_gated", + "target": "commands_end_session_freshness_clean_close_candidate_prompt_runs_only_when_stale_0_and_1_appears_done_item", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L251", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_1_refresh_the_primer_freshness_gated", + "target": "commands_end_session_refresh_flow_runs_when_stale_1_or_stale", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L275", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_1_refresh_the_primer_freshness_gated", + "target": "commands_end_session_fast_path_nothing_changed_since_last_close_out_check_first_cheap", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_1_refresh_the_primer_freshness_gated", + "target": "commands_end_session_backlog_verification_gated_by_commit_subject_overlap", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L62", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_2_session_reflection_for_learnings", + "target": "commands_end_session_resolve_extract_and_render", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L357", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_2_session_reflection_for_learnings", + "target": "commands_end_session_privacy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L390", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_2_session_reflection_for_learnings", + "target": "commands_end_session_output", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L396", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_2_session_reflection_for_learnings", + "target": "commands_end_session_capture_flow_batch_presentation_single_confirm", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L426", + "weight": 1.0 + }, + { + "source": "commands_end_session_step_3_final_checklist", + "target": "commands_end_session_gather_the_facts_and_render", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/end-session.md", + "source_location": "L479", + "weight": 1.0 + }, + { + "source": "commands_help", + "target": "commands_help_session_continuity_help", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/help.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_learning", + "target": "commands_learning_session_continuity_learning_arguments", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_6_regenerate_the_symptoms_index", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L114", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_1_preflight", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_7_bump_the_footer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L138", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_8_stage", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L148", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L156", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_2_gather_the_recipe", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L22", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_3_choose_section", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L36", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_4_compute_next_number_with_uniqueness_guard", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L52", + "weight": 1.0 + }, + { + "source": "commands_learning_session_continuity_learning_arguments", + "target": "commands_learning_step_5_insert_at_top_of_chosen_section", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learning.md", + "source_location": "L84", + "weight": 1.0 + }, + { + "source": "commands_learnings", + "target": "commands_learnings_session_continuity_learnings", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/learnings.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_primer", + "target": "commands_primer_session_continuity_primer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_1_detect_state", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_3_split_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L172", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_3b_outstanding_items_split", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L213", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_3c_backlog_rename_migration", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L247", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_3d_backlog_md_github_issues", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L288", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_4_refresh_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L309", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_4b_slim_migrate_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L356", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_5_check_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L387", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L432", + "weight": 1.0 + }, + { + "source": "commands_primer_session_continuity_primer", + "target": "commands_primer_step_2_init_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/primer.md", + "source_location": "L76", + "weight": 1.0 + }, + { + "source": "commands_spike_check", + "target": "commands_spike_check_session_continuity_spike_check_arguments", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/spike-check.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "commands_spike_check_session_continuity_spike_check_arguments", + "target": "commands_spike_check_the_stand_in_spike_checklist", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/spike-check.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "commands_spike_check_session_continuity_spike_check_arguments", + "target": "commands_spike_check_closing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/spike-check.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "commands_update", + "target": "commands_update_session_continuity_update", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "commands/update.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "contributing", + "target": "contributing_contributing_to_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "contributing_authoring_conventions", + "target": "contributing_slash_commands_commands_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L233", + "weight": 1.0 + }, + { + "source": "contributing_authoring_conventions", + "target": "contributing_hooks_hooks_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L241", + "weight": 1.0 + }, + { + "source": "contributing_authoring_conventions", + "target": "contributing_templates_skills_session_continuity_templates_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L250", + "weight": 1.0 + }, + { + "source": "contributing_authoring_conventions", + "target": "contributing_writing_style", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L256", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_development_workflow", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L161", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_before_you_start", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_authoring_conventions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L231", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_release_process", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L267", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_local_development", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_filing_good_issues", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L281", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_license_and_attribution", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L292", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_questions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L300", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_scope_first", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "contributing_contributing_to_session_continuity", + "target": "contributing_project_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L99", + "weight": 1.0 + }, + { + "source": "contributing_development_workflow", + "target": "contributing_branching", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L163", + "weight": 1.0 + }, + { + "source": "contributing_development_workflow", + "target": "contributing_commits", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L173", + "weight": 1.0 + }, + { + "source": "contributing_development_workflow", + "target": "contributing_specs_and_plans_for_non_trivial_changes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L192", + "weight": 1.0 + }, + { + "source": "contributing_development_workflow", + "target": "contributing_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L200", + "weight": 1.0 + }, + { + "source": "contributing_development_workflow", + "target": "contributing_pull_requests", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L211", + "weight": 1.0 + }, + { + "source": "contributing_development_workflow", + "target": "contributing_code_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L222", + "weight": 1.0 + }, + { + "source": "contributing_local_development", + "target": "contributing_prerequisites", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L29", + "weight": 1.0 + }, + { + "source": "contributing_local_development", + "target": "contributing_clone_and_install_locally", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L35", + "weight": 1.0 + }, + { + "source": "contributing_local_development", + "target": "contributing_run_the_plugin_against_a_scratch_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L47", + "weight": 1.0 + }, + { + "source": "contributing_local_development", + "target": "contributing_hook_smoke_tests", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "githooks_pre_commit", + "target": "githooks_pre_commit__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".githooks/pre-commit", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_backend_parity_gate", + "target": "hooks_backend_parity_gate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/backend-parity-gate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_evidence_gate", + "target": "hooks_evidence_gate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/evidence-gate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_flaky_gate", + "target": "hooks_flaky_gate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/flaky-gate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_learnings_surface", + "target": "hooks_learnings_surface_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/learnings-surface.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_agent_active", + "target": "hooks_lib_agent_active_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/agent-active.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_backlog_issues", + "target": "hooks_lib_backlog_issues_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/backlog-issues.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract", + "target": "hooks_lib_candidate_extract_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_render", + "target": "hooks_lib_candidate_render_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/candidate-render.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_checklist_assemble", + "target": "hooks_lib_checklist_assemble_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/checklist-assemble.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_count_entries", + "target": "hooks_lib_count_entries_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/count-entries.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index", + "target": "hooks_lib_learnings_index_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_peer_probes", + "target": "hooks_lib_peer_probes_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/peer-probes.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_log", + "target": "hooks_lib_perf_log_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_wrap", + "target": "hooks_lib_perf_wrap_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/perf-wrap.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_detect", + "target": "hooks_lib_primer_detect_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_freshness", + "target": "hooks_lib_primer_freshness_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-freshness.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_init_derive", + "target": "hooks_lib_primer_init_derive_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-init-derive.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_status", + "target": "hooks_lib_primer_status_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-status.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_validate", + "target": "hooks_lib_primer_validate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-validate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_render", + "target": "hooks_lib_render_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/render.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_require_script", + "target": "hooks_lib_require_script_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/require-script.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_resolve_transcript", + "target": "hooks_lib_resolve_transcript_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/resolve-transcript.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_test_count_rerun", + "target": "hooks_lib_test_count_rerun_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_lib_token_overlap", + "target": "hooks_lib_token_overlap_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/token-overlap.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_occurrence_gate", + "target": "hooks_occurrence_gate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/occurrence-gate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_pre_commit_check", + "target": "hooks_pre_commit_check_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/pre-commit-check.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_prompt_intercept", + "target": "hooks_prompt_intercept_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/prompt-intercept.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_proven_gate", + "target": "hooks_proven_gate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/proven-gate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_session_start", + "target": "hooks_session_start_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/session-start.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_smoke_gate", + "target": "hooks_smoke_gate_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/smoke-gate.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "hooks_version_check", + "target": "hooks_version_check_sh__entry", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/version-check.sh", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_administrative_marketplace_submission", + "target": "meta_administrative_marketplace_submission_anthropic_plugin_marketplace_submission", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_administrative_marketplace_submission_anthropic_plugin_marketplace_submission", + "target": "meta_administrative_marketplace_submission_who_s_the_target_user", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_administrative_marketplace_submission_anthropic_plugin_marketplace_submission", + "target": "meta_administrative_marketplace_submission_any_telemetry_external_calls", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L21", + "weight": 1.0 + }, + { + "source": "meta_administrative_marketplace_submission_anthropic_plugin_marketplace_submission", + "target": "meta_administrative_marketplace_submission_pre_filled_from_claude_plugin_plugin_json", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "meta_administrative_marketplace_submission_anthropic_plugin_marketplace_submission", + "target": "meta_administrative_marketplace_submission_what_does_it_do_why_would_i_install_it", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/administrative/marketplace-submission.md", + "source_location": "L3", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_resumption_checklist_2026_04_27_pause_point", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_what_s_done", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1345", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_resumption_checklist_2026_04_27_pause_point", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_what_was_learned_during_task_11_smoke_testing_and_fixed", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1365", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_resumption_checklist_2026_04_27_pause_point", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_what_s_still_pending", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1372", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_resumption_checklist_2026_04_27_pause_point", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_quick_resumption_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1383", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_11_local_install_smoke_test", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1009", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_2_restructure_move_skill_and_templates_into_plugin_layout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L103", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_12_publish_to_github", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1087", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_13_second_machine_install_verification", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1164", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_14_submit_to_anthropic_plugin_marketplace", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1202", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_15_wrap_up_verify_everything_is_green", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1249", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1300", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_resumption_checklist_2026_04_27_pause_point", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L1343", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_3_update_skill_md_tighten_description_and_add_plugin_affordances_note", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L166", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_4_update_plugin_json_version_bump_homepage_repository", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L218", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_5_create_session_continuity_primer_slash_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L269", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_6_create_session_continuity_learning_slash_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L368", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_7_create_hook_scripts_and_hooks_json", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L480", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_1_prep_git_init_and_safety_commit_of_current_state", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L50", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_8_create_github_workflows_release_yml", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L770", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_9_write_changelog_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L835", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_session_continuity_v0_2_public_release_implementation_plan", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_10_rewrite_readme_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L889", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_task_6_create_session_continuity_learning_slash_command", + "target": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release_n_title", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L433", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L17", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_3_bump_plugin_json_to_0_3_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L272", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_4_update_changelog_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L311", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_1_precondition_check_clean_starting_state", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L36", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_5_update_readme_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L364", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_6_update_skill_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L419", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_7_live_smoke_test_in_a_scratch_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L462", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_8_tag_and_publish_v0_3_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L606", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_2_write_commands_end_session_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L64", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_9_dogfood_run_session_continuity_end_session_on_this_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L692", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_task_10_wrap_up", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L745", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L767", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_session_continuity_end_session_v0_3_implementation_plan", + "target": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3_execution_handoff", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L813", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_10_final_verification_push", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L1051", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L1123", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_2_document_the_5_transcript_resolution_preamble_for_step_2", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L117", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_3_document_the_four_5_heuristics", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L252", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_1_document_the_1_outstanding_items_overlay_in_step_1", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L29", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_4_update_the_step_2_presentation_block_to_match_heuristic_output", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L400", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_5_bump_version_update_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L524", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_6_refresh_primer_for_v0_6_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L603", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_7_run_scenario_1_of_the_validation_matrix_clean_repo_no_commits", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L712", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_8_run_scenarios_2_5_of_the_validation_matrix", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L793", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_end_session_heuristic_pass_implementation_plan", + "target": "meta_superpowers_plans_2026_05_21_end_session_heuristic_pass_task_9_dogfood_test_run_session_continuity_end_session_on_this_very_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-05-21-end-session-heuristic-pass.md", + "source_location": "L929", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_fire_before_the_action_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_fire_before_the_action_implementation_plan", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_fire_before_the_action_implementation_plan", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L28", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_fire_before_the_action_implementation_plan", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_self_review_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L699", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_2_smoke_gate_hook", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L192", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_3_register_both_hooks_in_hooks_json", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L324", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_4_learning_command_optional_trigger_field", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L388", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_n_title", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L411", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_1_learnings_trigger_parsing_helper_test_first_pure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L43", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_5_template_skill_md_documentation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L439", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_6_version_bump_changelog_readme", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L484", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_7_mandatory_smoke_runner", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L542", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_15_fire_before_action_payload_contract_reference_for_all_hook_tasks", + "target": "meta_superpowers_plans_2026_06_15_fire_before_action_task_8_backfill_real_triggers_integration_check_on_this_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-15-fire-before-action.md", + "source_location": "L656", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check", + "target": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_occurrence_counter_gate_spike_check_command_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_global_constraints", + "target": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_1_occurrence_gate_hook_smoke_runner", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_global_constraints", + "target": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_2_extend_learning_with_occurrence_count_invariant_fields", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L271", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_global_constraints", + "target": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_3_spike_check_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L320", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_global_constraints", + "target": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_task_4_version_bump_readme_changelog_final_smoke", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L379", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_occurrence_counter_gate_spike_check_command_implementation_plan", + "target": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_occurrence_counter_gate_spike_check_command_implementation_plan", + "target": "meta_superpowers_plans_2026_06_17_occurrence_counter_and_spike_check_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-occurrence-counter-and-spike-check.md", + "source_location": "L463", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_proven_gate", + "target": "meta_superpowers_plans_2026_06_17_proven_gate_proven_gate_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_proven_gate_global_constraints", + "target": "meta_superpowers_plans_2026_06_17_proven_gate_task_1_the_proven_gate_hook_hermetic_smoke", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_proven_gate_global_constraints", + "target": "meta_superpowers_plans_2026_06_17_proven_gate_task_2_wire_the_hook_into_hooks_json", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L254", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_proven_gate_global_constraints", + "target": "meta_superpowers_plans_2026_06_17_proven_gate_task_3_version_bump_changelog_readme", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L296", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_proven_gate_proven_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_06_17_proven_gate_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_proven_gate_proven_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_06_17_proven_gate_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L356", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_06_17_proven_gate_proven_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_06_17_proven_gate_execution_handoff", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-06-17-proven-gate.md", + "source_location": "L373", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_task_2_step_3_checklist_row_re_derive_post_edit_example_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L177", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_task_3_validation_matrix_primer_refresh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L308", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L370", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_task_1_step_1_verification_sub_block_classify_verify_route", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L39", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_outstanding_items_verification_implementation_plan", + "target": "meta_superpowers_plans_2026_07_30_outstanding_items_verification_execution_handoff", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-07-30-outstanding-items-verification.md", + "source_location": "L398", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_2_escape_the_reason_at_the_point_of_emission", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L199", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_the_defect", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L21", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_3_record_why_the_tests_missed_it", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L305", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_4_release_0_12_2", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L349", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_deferred_with_reasons", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L417", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L422", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L60", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_hook_json_escaping_fix_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_task_1_the_contract_runner_write_it_first_watch_it_fail", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L73", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_the_defect", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_why_the_runners_are_green", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_the_defect", + "target": "meta_superpowers_plans_2026_08_12_hook_json_escaping_fix_end_state_invariant", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-hook-json-escaping-fix.md", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items", + "target": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_sessionstart_outstanding_items_surfacing_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-session-start-outstanding-items.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_global_constraints", + "target": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_task_1_extract_and_surface_outstanding_items_in_hooks_session_start_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-session-start-outstanding-items.md", + "source_location": "L22", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_sessionstart_outstanding_items_surfacing_implementation_plan", + "target": "meta_superpowers_plans_2026_08_12_session_start_outstanding_items_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-12-session-start-outstanding-items.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_primer_volatile_stable_split_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_2_commands_primer_md_split_mode_detection_split_mode_init_mode_update", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L227", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_3_commands_end_session_md_stage_project_context_md_when_touched", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L364", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_1_new_project_context_md_template_trim_session_primer_md_template", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L39", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_4_skills_session_continuity_skill_md_doc_updates", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L409", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_5_dogfood_split_this_repo_s_own_primer_bump_version_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L468", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_task_6_manual_validation_pass", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L567", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_primer_volatile_stable_split_implementation_plan", + "target": "meta_superpowers_plans_2026_08_13_primer_volatile_stable_split_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-13-primer-volatile-stable-split.md", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_per_repo_performance_logging_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_task_6_version_bump_changelog_readme_note", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1193", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_task_7_end_to_end_validation_log", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1281", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_task_2_hook_timing_wrapper_hooks_lib_perf_wrap_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L273", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_task_3_wire_hooks_hooks_json_through_the_wrapper", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L458", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_task_4_instrument_commands_primer_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L644", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_task_1_shared_writer_hooks_lib_perf_log_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L72", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_task_5_instrument_commands_end_session_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L931", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_per_repo_performance_logging_implementation_plan", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_self_review_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L1329", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_17_performance_logging_per_repo_performance_logging_implementation_plan", + "target": "meta_superpowers_plans_2026_08_17_performance_logging_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-17-performance-logging.md", + "source_location": "L41", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_commit_time_content_gates_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_commit_time_content_gates_implementation_plan", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_commit_time_content_gates_implementation_plan", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L868", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_2_proven_gate_commit_time_reference_implementation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L242", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_1_shared_gate_library_test_harness", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_3_smoke_gate_commit_time", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L382", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_4_evidence_gate_commit_time", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L466", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_5_backend_parity_gate_commit_time", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L539", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_6_occurrence_gate_commit_time", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L605", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_7_flaky_gate_dual_commit_message_staged_learnings", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L679", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_8_rewire_hooks_json_contract_runner_full_suite", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L754", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_global_constraints", + "target": "meta_superpowers_plans_2026_08_27_commit_time_content_gates_task_9_docs_version_learnings_primer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-27-commit-time-content-gates.md", + "source_location": "L831", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_2_repoint_session_start_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L118", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_1_new_template_retire_the_old_placeholder", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_3_primer_md_init_mode_seed_the_fourth_file", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L255", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_4_primer_md_split_mode_extend_with_the_new_detector", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L326", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_5_primer_md_refresh_flow_retarget_to_the_new_file", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L406", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_6_end_session_md_retarget_verification_add_the_migration_nudge", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L476", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_7_skill_md_document_the_fourth_file", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L572", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_8_claude_md_snippet_md_and_readme_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L634", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_9_migrate_this_repo_s_own_primer_dogfood", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L723", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_30_outstanding_items_file_standalone_outstanding_items_md_implementation_plan", + "target": "meta_superpowers_plans_2026_08_30_outstanding_items_file_task_10_end_to_end_scratch_validation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-30-outstanding-items-file.md", + "source_location": "L827", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_backlog_roadmap_rename_session_continuity_help_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_backlog_roadmap_rename_session_continuity_help_implementation_plan", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_12_readme_md_full_rename_five_file_language_help_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1070", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_13_dogfood_migrate_this_repo_s_own_session_continuity_instance", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1255", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_3_new_command_session_continuity_help", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L128", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_14_final_full_repo_verification_and_pr", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L1347", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_1_rename_template_outstanding_items_md_backlog_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_4_hooks_session_start_sh_rename_migration_nudge_branch", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L231", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_5_commands_primer_md_detection_init_mode_migration_step_3c_placeholder_rename", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L382", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_6_commands_doctor_md_track_backlog_md_and_roadmap_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L582", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_7_commands_end_session_md_rename_throughout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L638", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_8_skills_session_continuity_skill_md_rename_five_files_add_help_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L692", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_2_new_template_roadmap_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L79", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_9_skills_session_continuity_reference_md_rename", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L814", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_10_templates_claude_md_snippet_md_and_session_primer_md_rename_add_roadmap", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L869", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_global_constraints", + "target": "meta_superpowers_plans_2026_08_31_backlog_roadmap_help_task_11_plugin_json_version_bump_privacy_md_contributing_md_changelog_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-08-31-backlog-roadmap-help.md", + "source_location": "L951", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_end_session_step_2_cost_attribution_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_end_session_step_2_cost_attribution_implementation_plan", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_7_wire_commands_learning_md_steps_4_and_6_to_the_script", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1183", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_8_wire_commands_end_session_md_s_capture_flow_to_call_the_index_script_directly", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1259", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_9_end_to_end_validation_changelog_spec_backlog_cross_references", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L1304", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_2_candidate_extraction_script_change_1", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L151", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_1_shared_version_skew_guard", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_3_wire_commands_end_session_md_step_2_to_the_script", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L556", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_4_agent_active_time_script_change_2", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L625", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_5_wire_commands_end_session_md_step_4_to_agent_active_sh_retire_step_4_compute_only", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L804", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_end_session_step2_cost_attribution_task_6_learnings_md_derivations_script_change_3", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-end-session-step2-cost-attribution.md", + "source_location": "L861", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_learnings_generation_hardening_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_5_replay_harness_for_real_transcripts_f3_f4_f11", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1319", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_6_rewire_the_command_prose_f10_and_the_new_mode_error", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1455", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_7_run_the_ritual_end_to_end_and_release_f11", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1698", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_2_fence_aware_front_matter_safe_awk_passes_f8_f9", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L297", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_7_an_example_heading_inside_a_fence", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L329", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_1_write_gate_for_learnings_index_sh_f1_f2", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_3_failure_taxonomy_and_portability_for_candidate_extract_sh_f2_f6_f7", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L527", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_task_4_retune_the_heuristics_against_real_transcripts_f3_f4_f5", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L752", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_learnings_generation_hardening_implementation_plan", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_not_in_this_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1784", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_learnings_generation_hardening_implementation_plan", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_self_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L1791", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_learnings_generation_hardening_implementation_plan", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_findings_this_plan_closes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_learnings_generation_hardening_implementation_plan", + "target": "meta_superpowers_plans_2026_09_01_learnings_generation_hardening_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-01-learnings-generation-hardening.md", + "source_location": "L37", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_end_session_step_2_rendering_and_reference_relocation_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_end_session_step_2_rendering_and_reference_relocation_implementation_plan", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_end_session_step_2_rendering_and_reference_relocation_implementation_plan", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_6_full_regression_pass_and_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L1070", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_2_candidate_render_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L211", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_1_resolve_transcript_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L41", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_3_relocate_heuristics_documentation_to_heuristics_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L442", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_4_rewrite_commands_end_session_md_step_2", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L619", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_file_structure", + "target": "meta_superpowers_plans_2026_09_02_end_session_step2_rendering_plan_task_5_on_demand_transcript_resolution_in_step_4", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-end-session-step2-rendering-plan.md", + "source_location": "L972", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_fresh_install_count_defects_implementation_plan_phase_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_fresh_install_count_defects_implementation_plan_phase_0", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_smoke_coverage_mandatory", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L229", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_fresh_install_count_defects_implementation_plan_phase_0", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L237", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_fresh_install_count_defects_implementation_plan_phase_0", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_the_two_reproductions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L32", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_fresh_install_count_defects_implementation_plan_phase_0", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_why_a_shared_helper_rather_than_editing_the_templates_alone", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L57", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_fresh_install_count_defects_implementation_plan_phase_0", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L75", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_2_rewrite_session_start_sh_s_two_call_sites", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L127", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_3_rewrite_primer_md_check_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L162", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_4_fix_the_two_templates", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L183", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_5_release_bookkeeping", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L204", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_fresh_install_count_defects_task_1_count_entries_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md", + "source_location": "L89", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_zero_turn_read_only_commands_implementation_plan_phase_1", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_1_measure_the_interception_surface_gate", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L119", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_2_renderer_layer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L186", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_3_interception_layer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L244", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_4_command_stubs_with_working_fallback_bodies", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L302", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_5_interception_smoke_test_mandatory", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L337", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_task_6_docs_changelog_version", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L365", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_zero_turn_read_only_commands_implementation_plan_phase_1", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_deliberately_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L400", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_zero_turn_read_only_commands_implementation_plan_phase_1", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_status_tasks_2_6_are_provisional_pending_task_1", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L60", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_zero_turn_read_only_commands_implementation_plan_phase_1", + "target": "meta_superpowers_plans_2026_09_02_zero_turn_read_only_commands_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-02-zero-turn-read-only-commands.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_determinism_phase_3_shared_mechanics_library_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_determinism_phase_3_shared_mechanics_library_implementation_plan", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_determinism_phase_3_shared_mechanics_library_implementation_plan", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_6_doc_pointers_regression_pass_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L1040", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_2_primer_status_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L356", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_1_perf_log_sh_add_mark_and_since", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_3_wire_primer_status_sh_into_hooks_session_start_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L542", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_4_wire_primer_status_sh_into_commands_primer_md_check_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L635", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_file_structure", + "target": "meta_superpowers_plans_2026_09_03_shared_mechanics_library_task_5_collapse_the_four_epoch_blocks_in_commands_end_session_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-03-shared-mechanics-library.md", + "source_location": "L737", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_determinism_phase_5_backlog_mechanics_and_the_commit_overlap_gate_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_determinism_phase_5_backlog_mechanics_and_the_commit_overlap_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_determinism_phase_5_backlog_mechanics_and_the_commit_overlap_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L28", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_2_backlog_item_sh_mint_tag_in_use_renumber", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L179", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_3_commit_overlap_sh_tokenize_stopword_drop_threshold_intersection", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L432", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_1_fix_candidate_extract_jq_s_overlap_closes_40", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L47", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_4_wire_commands_primer_md_to_backlog_item_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L605", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_5_wire_commands_end_session_md_to_commit_overlap_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L776", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_file_structure", + "target": "meta_superpowers_plans_2026_09_07_determinism_phase_5_backlog_mechanics_task_6_docs_backlog_changelog_version_bump", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-determinism-phase-5-backlog-mechanics.md", + "source_location": "L922", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_github_issues_backlog", + "target": "meta_superpowers_plans_2026_09_07_github_issues_backlog_github_issues_backlog_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_github_issues_backlog_github_issues_backlog_implementation_plan", + "target": "meta_superpowers_plans_2026_09_07_github_issues_backlog_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_github_issues_backlog_github_issues_backlog_implementation_plan", + "target": "meta_superpowers_plans_2026_09_07_github_issues_backlog_spec_coverage", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L222", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_github_issues_backlog_global_constraints", + "target": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_3_commands_skill_docs_template_deletion_version_bump", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L170", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_github_issues_backlog_global_constraints", + "target": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_4_migrate_this_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L202", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_github_issues_backlog_global_constraints", + "target": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_1_backlog_issues_sh_smoke", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_07_github_issues_backlog_global_constraints", + "target": "meta_superpowers_plans_2026_09_07_github_issues_backlog_task_2_wire_render_session_start_primer_status_rewrite_smokes_delete_awk", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-07-github-issues-backlog.md", + "source_location": "L82", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_determinism_phase_4_end_session_step_3_checklist_assembly_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_one_such_literal_printf_line_per_remaining_open_item_tag_first_the", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L612", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_n_identity_never_the_ephemeral_1_n_list_position_verdict_second", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L613", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_still_open_appears_done_manual_citation_third_the_same_evidence_string", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L614", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_already_decided_above_not_auto_verifiable_for_non_code_items_no", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L615", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_related_commits_since_last_refresh_not_re_checked_this_session_for", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L616", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_overlap_gated_ones", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L617", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_primer_learnings_json_commit_subject_json_set_these_three_from_what", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L794", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_step_1_step_2_actually_did_this_invocation_see_the_field_notes_below", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L795", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_determinism_phase_4_end_session_step_3_checklist_assembly_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_determinism_phase_4_end_session_step_3_checklist_assembly_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_file_structure", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_1_hooks_lib_checklist_assemble_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_file_structure", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_2_perf_log_sh_gitignore_the_new_scratch_tsv", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L512", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_file_structure", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_3_commands_end_session_md_step_1_fast_path_count_and_the_backlog_verdict_tsv", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L553", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_overlap_gated_ones", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_4_commands_end_session_md_step_3_call_checklist_assemble_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L642", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_step_1_step_2_actually_did_this_invocation_see_the_field_notes_below", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_5_commands_end_session_md_step_4_drop_the_printed_sign_off_keep_only_timing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L857", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_step_1_step_2_actually_did_this_invocation_see_the_field_notes_below", + "target": "meta_superpowers_plans_2026_09_08_determinism_phase_4_checklist_assembly_task_6_doc_pointers_regression_pass_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-determinism-phase-4-checklist-assembly.md", + "source_location": "L931", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_2_parser_single_complete_entry_quoted_and_bare_values", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L228", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_3_parser_multiple_entries_comments_blank_lines", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L301", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_4_parser_invalid_entries_incomplete_or_in_claim_pattern_are_dropped_with_a_warning_don_t_corrupt_neighbors", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L348", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_5_wire_the_parser_into_post_merge_preserve_legacy_fallback", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L435", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_6_update_the_design_sketch_doc_in_this_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L687", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_docguard_generalization_docguard_generalization_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_docguard_generalization_task_1_parser_library_empty_missing_file", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-docguard-generalization.md", + "source_location": "L90", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_primer_detect", + "target": "meta_superpowers_plans_2026_09_08_primer_detect_determinism_phase_6_sub_project_a_primer_detect_sh_jq_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_primer_detect_determinism_phase_6_sub_project_a_primer_detect_sh_jq_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_primer_detect_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_primer_detect_determinism_phase_6_sub_project_a_primer_detect_sh_jq_implementation_plan", + "target": "meta_superpowers_plans_2026_09_08_primer_detect_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_primer_detect_file_structure", + "target": "meta_superpowers_plans_2026_09_08_primer_detect_task_1_hooks_lib_primer_detect_jq_hooks_lib_primer_detect_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_primer_detect_file_structure", + "target": "meta_superpowers_plans_2026_09_08_primer_detect_task_2_commands_primer_md_call_the_script", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L428", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_08_primer_detect_file_structure", + "target": "meta_superpowers_plans_2026_09_08_primer_detect_task_3_doc_pointers_regression_pass_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-08-primer-detect.md", + "source_location": "L627", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate", + "target": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_determinism_phase_7_derived_value_gate_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_determinism_phase_7_derived_value_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_1_fix_54_converge_end_session_md_s_drift_check_rerun_onto_test_count_rerun_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L117", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_determinism_phase_7_derived_value_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_2_hooks_derived_value_gate_sh_smoke_test", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L272", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_determinism_phase_7_derived_value_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_3_wire_into_hooks_json", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L493", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_determinism_phase_7_derived_value_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_task_4_doc_pointers_security_md_correction_changelog_version_bump", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L544", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_determinism_phase_7_derived_value_gate_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_determinism_phase_7_derived_value_gate_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-determinism-phase-7-derived-value-gate.md", + "source_location": "L77", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_init_derive", + "target": "meta_superpowers_plans_2026_09_09_primer_init_derive_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_init_derive_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_primer_init_derive_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L30", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_init_derive_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_primer_init_derive_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L74", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_init_derive_file_structure", + "target": "meta_superpowers_plans_2026_09_09_primer_init_derive_task_2_commands_primer_md_call_the_script", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L505", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_init_derive_file_structure", + "target": "meta_superpowers_plans_2026_09_09_primer_init_derive_task_3_doc_pointers_regression_pass_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L661", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_init_derive_file_structure", + "target": "meta_superpowers_plans_2026_09_09_primer_init_derive_task_1_hooks_lib_primer_init_derive_jq_hooks_lib_primer_init_derive_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-init-derive.md", + "source_location": "L88", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_thin_hard_template_session_primer_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_2_primer_validate_sh_smoke", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L137", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_3_primer_freshness_sh_smoke", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L193", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_4_thin_template_copy_churn_templates_only", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L232", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_5_wire_sessionstart", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L258", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_6_doctor_command_wiring", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L301", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_7_primer_end_session_pre_commit_prose", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L340", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_8_dogfood_privacy_copy_version_bump", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L376", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_task_1_peer_probes_sh_smoke", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L56", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_thin_hard_template_session_primer_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_thin_hard_template_session_primer_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_file_map", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L32", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_thin_hard_template_session_primer_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_spec_coverage_checklist", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L425", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_thin_hard_template_session_primer_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_primer_thin_hard_template_self_review_notes_post_caveman_review", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md", + "source_location": "L448", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_test_count_rerun", + "target": "meta_superpowers_plans_2026_09_09_test_count_rerun_determinism_phase_6_sub_project_b_test_count_rerun_sh_jq_implementation_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_test_count_rerun_determinism_phase_6_sub_project_b_test_count_rerun_sh_jq_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_test_count_rerun_global_constraints", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_test_count_rerun_determinism_phase_6_sub_project_b_test_count_rerun_sh_jq_implementation_plan", + "target": "meta_superpowers_plans_2026_09_09_test_count_rerun_file_structure", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_test_count_rerun_file_structure", + "target": "meta_superpowers_plans_2026_09_09_test_count_rerun_task_1_hooks_lib_test_count_rerun_jq_hooks_lib_test_count_rerun_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L39", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_test_count_rerun_file_structure", + "target": "meta_superpowers_plans_2026_09_09_test_count_rerun_task_2_commands_primer_md_call_the_script", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L506", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_09_09_test_count_rerun_file_structure", + "target": "meta_superpowers_plans_2026_09_09_test_count_rerun_task_3_doc_pointers_regression_pass_changelog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-09-09-test-count-rerun.md", + "source_location": "L601", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_docguard_design_sketch", + "target": "meta_superpowers_recommendations_docguard_design_sketch_design_sketch_generalized_docs_current_gate", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/docguard-design-sketch.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_docguard_design_sketch_design_sketch_generalized_docs_current_gate", + "target": "meta_superpowers_recommendations_docguard_design_sketch_implemented_2026_09_08", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/docguard-design-sketch.md", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_docguard_design_sketch_design_sketch_generalized_docs_current_gate", + "target": "meta_superpowers_recommendations_docguard_design_sketch_the_gap", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/docguard-design-sketch.md", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521", + "target": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_1_drift_detection_what_works_what_misses", + "target": "meta_superpowers_recommendations_improvements_20260521_what_works", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_1_drift_detection_what_works_what_misses", + "target": "meta_superpowers_recommendations_improvements_20260521_what_misses", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L9", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_4_learnings_entry_creation_and_search", + "target": "meta_superpowers_recommendations_improvements_20260521_numbering_should_be_automatic", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_4_learnings_entry_creation_and_search", + "target": "meta_superpowers_recommendations_improvements_20260521_cross_references_decay", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L47", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_4_learnings_entry_creation_and_search", + "target": "meta_superpowers_recommendations_improvements_20260521_search_by_symptom_is_hard", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L50", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_4_learnings_entry_creation_and_search", + "target": "meta_superpowers_recommendations_improvements_20260521_last_reviewed_dating_is_manual_always_stale", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L53", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_6_the_primer_file_is_now_320_lines_context_cost", + "target": "meta_superpowers_recommendations_improvements_20260521_mix_of_stable_and_volatile_content", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L71", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_6_the_primer_file_is_now_320_lines_context_cost", + "target": "meta_superpowers_recommendations_improvements_20260521_closed_outstanding_items_pile_up", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L77", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_10_quick_wins_ranked", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L112", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_2_primer_only_commit_rule_needs_branch_aware_nuance", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L14", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_3_init_mode_could_derive_much_more", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_1_drift_detection_what_works_what_misses", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L3", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_4_learnings_entry_creation_and_search", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L36", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_5_end_session_skill_never_fired_during_a_6_hour_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L56", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_6_the_primer_file_is_now_320_lines_context_cost", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_7_schema_validation_for_primer_fields", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L80", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_8_plugin_awareness_of_sibling_tools", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L88", + "weight": 1.0 + }, + { + "source": "meta_superpowers_recommendations_improvements_20260521_session_continuity_plugin_usage_feedback_recommendations", + "target": "meta_superpowers_recommendations_improvements_20260521_9_specific_friction_moments_worth_recording", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/recommendations/improvements_20260521.md", + "source_location": "L96", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands_primer_md_session_continuity_primer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L87", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands_learning_md_session_continuity_learning", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L95", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L105", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_github_workflows_release_yml", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L187", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_readme_md_rewritten_target_100_lines", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L216", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_changelog_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L232", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_gitignore", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L265", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_plugin_json", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L52", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_skills_session_continuity_skill_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L69", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_commands", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L83", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_distribution_plan", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_1_github_repo_setup", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L278", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_distribution_plan", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_2_local_install_smoke_test", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L288", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_distribution_plan", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_3_marketplace_submission", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L292", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_distribution_plan", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_4_passive_promotion_only", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L296", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_distribution_plan", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_step_5_ongoing_maintenance", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L300", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks_session_start_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L131", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks_pre_commit_check_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L143", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_hooks_version_check_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L158", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_repo_layout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_distribution_plan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L276", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_risks_and_mitigations", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L308", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_acceptance_criteria", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L318", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_goal", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_session_continuity_v0_2_public_release_design", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design_component_designs", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-27-session-continuity-v0.2-public-release-design.md", + "source_location": "L50", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_architecture", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_single_file_command_subroutine_by_reference", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L126", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_architecture", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_no_new_hooks_no_new_templates", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L139", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_behavior", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_non_behaviors_explicit", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L118", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_behavior", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_precondition", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L37", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_behavior", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_step_1_refresh_the_primer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L45", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_behavior", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_step_2_session_reflection_for_learnings", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L59", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_behavior", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_step_3_final_checklist", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L82", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_architecture", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L124", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_versioning_release", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L146", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_testing_strategy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L153", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_goal", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_acceptance_criteria", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L184", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_open_questions_not_blocking", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L194", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L20", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_out_of_scope_decided_during_brainstorm", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L202", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_command_surface", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L28", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_behavior", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L35", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_session_continuity_end_session_design_spec", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_testing_strategy", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_layer_1_prose_consistency_check", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L157", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_testing_strategy", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_layer_2_live_smoke_test_in_a_scratch_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L167", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_04_28_end_session_command_design_testing_strategy", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design_layer_3_dogfood_in_the_session_continuity_repo_itself", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-04-28-end-session-command-design.md", + "source_location": "L180", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_presentation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L151", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_transcript_resolution", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L214", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_edge_cases", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L238", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_testing_validation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L267", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_goal", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L29", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_compatibility", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L315", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L35", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_architecture", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_heuristic_specs", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_design_session_continuity_end_session_heuristic_pass", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_heuristic_specs", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_refusals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L141", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_heuristic_specs", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_1_outstanding_items_match_step_1_overlay", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L69", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_heuristic_specs", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_5_learnings_heuristics_step_2_replacement", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L98", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_presentation", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_step_1_refresh_output", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L153", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_presentation", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_step_2_session_reflection_output", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L174", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_presentation", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_cap_behavior", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L201", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_presentation", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_step_3_checklist_updates", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L207", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_testing_validation", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_manual_validation_matrix", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L272", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_testing_validation", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_dogfood_test", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L297", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_testing_validation", + "target": "meta_superpowers_specs_2026_05_21_end_session_heuristic_pass_design_acceptance_criteria", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-05-21-end-session-heuristic-pass-design.md", + "source_location": "L305", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_a_learnings_retrieval_hook", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_template_change", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L107", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_a_learnings_retrieval_hook", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_entry_trigger_syntax", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L53", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_a_learnings_retrieval_hook", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_hooks_learnings_surface_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L74", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_a_learnings_retrieval_hook", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_learning_command_change", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L95", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_b_smoke_gate_hook", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_hooks_smoke_gate_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L114", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_b_smoke_gate_hook", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_escape_hatch", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L141", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_b_smoke_gate_hook", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_hook_ordering", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L149", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_b_smoke_gate_hook", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L112", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_cross_cutting", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L156", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_testing_this_plugin_smokes_itself", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L168", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L29", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L3", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L40", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_15_fire_before_action_design_fire_before_the_action_session_continuity_v0_8_0", + "target": "meta_superpowers_specs_2026_06_15_fire_before_action_design_component_a_learnings_retrieval_hook", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-15-fire-before-action-design.md", + "source_location": "L51", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_mechanics_reuse_proven_gate_sh_skeleton", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L107", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_wiring", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L136", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_self_reference_trap_learnings_7_1", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L149", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_testing_hermetic_no_containers", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L157", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_what_it_does_one_sentence", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_scope_decided", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_detection_rule", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L52", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_escape_hatch_explicit_skip_with_reason", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L72", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_learning_command_extension", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L84", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_3c_spike_check_command", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_what_it_does_one_sentence_182", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L182", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_3c_spike_check_command", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_why_a_command_not_a_hook", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L189", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_3c_spike_check_command", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_form", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L199", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_3c_spike_check_command", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_front_matter_registration", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L229", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_3c_spike_check_command", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L241", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_the_two_problems", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_3c_spike_check_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L180", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_versioning_ship", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L251", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_success_criteria_the_invariants_for_this_workstream", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L261", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L270", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_occurrence_counter_gate_spike_check_command_change_the_odds_2_3c", + "target": "meta_superpowers_specs_2026_06_17_occurrence_counter_and_spike_check_design_deliverable_2_occurrence_gate_hook", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-occurrence-counter-and-spike-check-design.md", + "source_location": "L36", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_mechanics_reuse_smoke_gate_sh_exactly", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_wiring", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L115", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_the_problem_this_gate_exists_to_stop", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L12", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_testing_hermetic_no_containers", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L129", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_self_reference_trap_learnings_7_1_read_before_implementing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L151", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_versioning_ship", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L174", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_success_criterion_the_invariant", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L184", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_out_of_scope_other_change_the_odds_deliverables_sequenced_after_this", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L193", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_what_it_does_one_sentence", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L26", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_scope_decided", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L33", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_detection_rule", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_escape_hatch_explicit_skip_with_reason", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L70", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_06_17_proven_gate_design_proven_gate_make_proven_a_checkable_claim_not_a_feeling", + "target": "meta_superpowers_specs_2026_06_17_proven_gate_design_mechanics_reuse_smoke_gate_sh_exactly", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-06-17-proven-gate-design.md", + "source_location": "L85", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_edge_cases", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L123", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L135", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_validation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L143", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_constraint_that_shapes_the_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_decisions_from_brainstorming", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L33", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L6", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_verdicts", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L61", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_design_outstanding_items_code_verification_in_session_continuity_end_session", + "target": "meta_superpowers_specs_2026_07_30_outstanding_items_verification_design_placement_runs_in_step_1_above_the_drift_branch_reported_in_step_3", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-07-30-outstanding-items-verification-design.md", + "source_location": "L81", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design", + "target": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "target": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_decision", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "target": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_output_shape", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "target": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L6", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "target": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_implementation_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "target": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L82", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_design_sessionstart_surfaces_outstanding_items", + "target": "meta_superpowers_specs_2026_08_12_session_start_outstanding_items_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-12-session-start-outstanding-items-design.md", + "source_location": "L99", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_design_split_session_primer_md_into_volatile_stable_files", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_commands_learning_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L105", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_skills_session_continuity_skill_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L109", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_this_repo_dogfood", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L123", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_migration", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L46", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_init_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L68", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_hooks", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L77", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_commands_end_session_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L88", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_design_split_session_primer_md_into_volatile_stable_files", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L130", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_design_split_session_primer_md_into_volatile_stable_files", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L139", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_design_split_session_primer_md_into_volatile_stable_files", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_decision", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L30", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_design_split_session_primer_md_into_volatile_stable_files", + "target": "meta_superpowers_specs_2026_08_13_primer_volatile_stable_split_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-13-primer-volatile-stable-split-design.md", + "source_location": "L6", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L10", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_mechanism_1_shipped_hooks_wrapper_not_inline", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L102", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_mechanism_2_slash_commands_self_reported", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L144", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L20", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_mechanism_3_shared_writer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L245", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_testing_plan_not_yet_executed_nothing_in_this_spec_is_implemented", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L263", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_storage", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_17_performance_logging_design_per_repo_performance_logging_design", + "target": "meta_superpowers_specs_2026_08_17_performance_logging_design_schema", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-17-performance-logging-design.md", + "source_location": "L68", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_components", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_per_gate_commit_mode", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L104", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_components", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_flaky_gate_sh_stays_dual", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L124", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_components", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_hooks_hooks_json_rewire", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L133", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_components", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_hooks_lib_gate_common_sh_new_sourced", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L75", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_false_trigger_reduction_problem_2", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L145", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_error_handling", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L166", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L177", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_docs_version", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L198", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_tradeoffs_accepted", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L210", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_goal_invariant", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L37", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_decisions_from_brainstorming", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_approach_selected", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L53", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_components", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L73", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_design_commit_time_content_gates_false_trigger_reduction", + "target": "meta_superpowers_specs_2026_08_27_commit_time_content_gates_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-27-commit-time-content-gates-design.md", + "source_location": "L9", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_consumer_changes", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_hooks_session_start_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L116", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_consumer_changes", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_commands_end_session_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L145", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_consumer_changes", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_commands_primer_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L182", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_consumer_changes", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_skill_md_templates_claude_md_snippet_md_readme_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L216", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_consumer_changes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L114", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_backward_compatibility", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L235", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_migration_of_this_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L253", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L262", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L286", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_decisions_from_brainstorming", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L37", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_design_a_standalone_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_file_session_continuity_outstanding_items_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L52", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_file_session_continuity_outstanding_items_md", + "target": "meta_superpowers_specs_2026_08_30_outstanding_items_file_design_item_shape", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-30-outstanding-items-file-design.md", + "source_location": "L81", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_migration_primer_md_step_3c_new", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L128", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_session_continuity_help_command_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L179", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_rollout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L214", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_open_questions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L228", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L31", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_file_inventory_every_touchpoint", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L6", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_backlog_md_rename_details", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L87", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_design_backlog_md_rename_roadmap_md_and_session_continuity_help", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_roadmap_md_new_stub_template", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L97", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_migration_primer_md_step_3c_new", + "target": "meta_superpowers_specs_2026_08_31_backlog_roadmap_help_design_session_start_sh_new_elif_branch", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-08-31-backlog-roadmap-help-design.md", + "source_location": "L171", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_change_1_ship_the_extraction_and_the_heuristics_as_one_script", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L131", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_change_2_measure_agent_active_time_instead_of_guessing_at_it", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L162", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_change_3_ship_the_learnings_derivations_as_a_script", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L207", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L223", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_invariants", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L114", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L129", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L14", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_testing_plan_nothing_here_is_implemented_yet", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L230", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_what_the_measurement_shows", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L26", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_end_session_step_2_cost_attribution_and_heuristic_execution_design", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_resolved_decisions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L269", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_what_the_measurement_shows", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_4_the_derived_content_steps_are_not_running_at_scale", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L102", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_what_the_measurement_shows", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_1_compute_only_counts_human_idle_as_compute", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L28", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_what_the_measurement_shows", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_2_the_real_step_2_cost_is_sequential_re_filtering", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L75", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_what_the_measurement_shows", + "target": "meta_superpowers_specs_2026_09_01_end_session_step2_cost_attribution_design_finding_3_the_shipped_shell_work_is_free", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-01-end-session-step2-cost-attribution-design.md", + "source_location": "L91", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_what_stays_model_work", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L114", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_phases", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L144", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_the_invariant", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L21", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L249", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_open_questions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L258", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_determinism_program_design", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_evidence", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L40", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_evidence", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_prompt_bytes_by_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_determinism_program_design_evidence", + "target": "meta_superpowers_specs_2026_09_02_determinism_program_design_six_categories_of_avoidable_work", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-determinism-program-design.md", + "source_location": "L64", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_transcript_resolution_moves_here_too", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L119", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_where_the_heuristics_documentation_goes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L163", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_what_step_2_becomes_in_the_prompt", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L181", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_the_output_schema_as_it_actually_exists", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L56", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_a_sibling_renderer_not_a_flag_on_the_extractor", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L71", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_the_renderer_owns_three_of_four_modes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L95", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_estimated_effect", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L193", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L204", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_the_correction_that_shapes_the_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L22", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L221", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_two_defects_found_while_reading_the_source", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L37", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_end_session_step_2_rendering_and_reference_relocation_phase_2_design", + "target": "meta_superpowers_specs_2026_09_02_end_session_step2_rendering_design_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-end-session-step2-rendering-design.md", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_method", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_end_to_end_confirmation_blocking_a_real_slash_command_costs_zero_turns", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L130", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_amendments_to_tasks_2_6", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L148", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_cleanup", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L166", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_1_does_a_slash_command_reach_userpromptsubmit_and_what_is_prompt", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L37", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_2_what_is_command_name_for_a_plugin_scoped_command", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L53", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_3_how_does_a_multi_line_reason_render_and_where_does_it_truncate", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L75", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_zero_turn_read_only_commands_design_task_1_measurement_results", + "target": "meta_superpowers_specs_2026_09_02_zero_turn_read_only_commands_design_measurement_4_is_suppressoriginalprompt_top_level_or_inside_hookspecificoutput", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-02-zero-turn-read-only-commands-design.md", + "source_location": "L94", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_doctor_commands", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L148", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_privacy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L187", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_this_repo_s_cut", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L200", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L22", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_tests", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L227", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_docs_version", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L250", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L258", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L39", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_decisions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L6", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_design_github_issues_replace_backlog_md", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_runtime", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L74", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_doctor_commands", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_init", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L150", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_doctor_commands", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_migrate", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L156", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_doctor_commands", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_doctor", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L171", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_primer_doctor_commands", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_session_continuity_backlog_and_end_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L178", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_runtime", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_call_sites", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L123", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_runtime", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_write_path_skill_commands_not_a_daemon", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L131", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_runtime", + "target": "meta_superpowers_specs_2026_09_07_github_issues_backlog_design_hooks_lib_backlog_issues_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-07-github-issues-backlog-design.md", + "source_location": "L78", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_error_handling", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L133", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L145", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_rollout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L168", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L178", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_architecture", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_context", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_08_primer_detect_design_design_primer_detect_sh_jq_determinism_phase_6_sub_project_a", + "target": "meta_superpowers_specs_2026_09_08_primer_detect_design_output_contract", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-08-primer-detect-design.md", + "source_location": "L59", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_init_derive_design", + "target": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "target": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L12", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "target": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_output_contract", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L120", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "target": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L210", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "target": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L242", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "target": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_context", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L3", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_determinism_phase_6_sub_project_d_primer_init_derive_sh_jq_design", + "target": "meta_superpowers_specs_2026_09_09_primer_init_derive_design_architecture", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-init-derive-design.md", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_content_contract", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_section_rules", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L157", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_content_contract", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L127", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L173", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_migration", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L267", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L280", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_privacy_product_copy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L300", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_open_implementation_choices_plan_not_design", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L308", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_success_criteria", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L323", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_non_goals", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_decisions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_design_thin_hard_template_session_primer_md_engrim_graphify_required", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_new_helper_hooks_lib_peer_probes_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L175", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_new_helper_hooks_lib_primer_validate_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L194", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_sessionstart_hooks_session_start_sh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L207", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_doctor", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L224", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_session_continuity_primer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L236", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_pre_commit_nudge", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L255", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_runtime", + "target": "meta_superpowers_specs_2026_09_09_primer_thin_hard_template_design_session_continuity_end_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md", + "source_location": "L260", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_error_handling", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L150", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_testing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L161", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_rollout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L184", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_problem", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_out_of_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L193", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_recorded_count_format_existing_unchanged", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L31", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_architecture", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L47", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_context", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_design_test_count_rerun_sh_jq_determinism_phase_6_sub_project_b", + "target": "meta_superpowers_specs_2026_09_09_test_count_rerun_design_output_contract", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/specs/2026-09-09-test-count-rerun-design.md", + "source_location": "L84", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_dogfood_test_this_session", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_step_1_outcome", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L114", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_dogfood_test_this_session", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_step_2_outcome", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L131", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_dogfood_test_this_session", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_acceptance_gate", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L159", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_dogfood_test_this_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L107", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_1_clean_repo_no_commits_since_last_primer_refresh", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_2_commits_without_matches", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L39", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_3_commit_with_stem_intersection_match", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L57", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_4_retry_burst_heuristic_a", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L75", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_05_21_end_session_heuristics_validation_log_end_session_heuristic_pass_v0_6_0", + "target": "meta_superpowers_validation_2026_05_21_end_session_heuristics_scenario_5_revert_reset_heuristic_b", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-05-21-end-session-heuristics.md", + "source_location": "L91", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_in_repo_manual_check_real_grep_count", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L109", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_acceptance_gate", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L119", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_1_case_a_drift_detected_appears_done_item_routes_to_the_combined_prompt_as_a_close_candidate_with_cited_evidence", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_2_case_b_drift_clean_verification_runs_no_prompt_verdict_held_for_step_3_only", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_3_case_c_user_closes_an_appears_done_item_at_the_prompt_then_step_3_re_derives_item_absent_marker_checkmark", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L37", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_4_case_d_drift_clean_stale_item_step_3_reports_it_marker_warning_no_deletion", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_5_never_auto_close_invariant_appears_done_item_no_changes_reply_item_still_present_in_primer_afterward_step_3_still_warning_appears_done", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L61", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_6_non_code_item_marketplace_submission_verdict_manual_not_auto_verifiable_never_asserted", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L73", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_7_ambiguous_grep_match_inside_a_comment_manual_not_appears_done_bias_rule", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L85", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_validation_log_outstanding_items_verification_v0_12_0", + "target": "meta_superpowers_validation_2026_07_30_outstanding_items_verification_scenario_8_no_outstanding_items_heading_verification_skipped_row_reads_none_tracked", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-07-30-outstanding-items-verification.md", + "source_location": "L97", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_3_end_session_fast_path_nothing_changed_since_last_close_out", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L128", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_4_end_session_full_step_1_path_drift_appears_done_item", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L191", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_1_primer_init_mode_no_primer_exists", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_full_captured_log_all_4_runs_in_order", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L260", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_concerns_found_during_this_validation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L287", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_acceptance_gate", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L323", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_08_17_performance_logging_validation_log_per_repo_performance_logging_v0_15_0", + "target": "meta_superpowers_validation_2026_08_17_performance_logging_scenario_2_primer_refresh_mode_unrelated_code_staged", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-08-17-performance-logging.md", + "source_location": "L74", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_validation_log_learnings_generation_hardening_end_to_end_v0_25_0", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_2_step_2_3_adapted_scratch_repo_mechanical_verification", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_the_adaptation_stated_plainly", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L117", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_2_step_2_3_adapted_scratch_repo_mechanical_verification", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_actual_run_post_fix_directly_in_zsh_no_bash_c_wrapper", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L166", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_2_step_2_3_adapted_scratch_repo_mechanical_verification", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_the_four_end_to_end_invariants_plan_step_3", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L199", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_3_fresh_replay_against_real_transcripts_task_5_s_harness_re_run_now", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_before_after_candidate_counts", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L250", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_validation_log_learnings_generation_hardening_end_to_end_v0_25_0", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_2_step_2_3_adapted_scratch_repo_mechanical_verification", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L115", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_validation_log_learnings_generation_hardening_end_to_end_v0_25_0", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_0_a_bug_found_and_fixed_during_this_verification", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_validation_log_learnings_generation_hardening_end_to_end_v0_25_0", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_3_fresh_replay_against_real_transcripts_task_5_s_harness_re_run_now", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L215", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_validation_log_learnings_generation_hardening_end_to_end_v0_25_0", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_4_summary_what_held_what_didn_t_what_wasn_t_run", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L266", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_validation_log_learnings_generation_hardening_end_to_end_v0_25_0", + "target": "meta_superpowers_validation_2026_09_01_learnings_hardening_verification_1_smoke_suites", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-01-learnings-hardening-verification.md", + "source_location": "L99", + "weight": 1.0 + }, + { + "source": "meta_superpowers_validation_2026_09_08_token_overlap", + "target": "meta_superpowers_validation_2026_09_08_token_overlap_validation_log_token_overlap_gate_consolidation_determinism_phase_5_42", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/validation/2026-09-08-token-overlap.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "privacy", + "target": "privacy_privacy_policy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_what_data_the_plugin_handles", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_external_network_calls", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L20", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_what_the_plugin_does_not_do", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L50", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_third_party_services", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L58", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_data_retention", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L62", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_changes_to_this_policy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L66", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_short_version", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "privacy_privacy_policy", + "target": "privacy_contact", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "PRIVACY.md", + "source_location": "L70", + "weight": 1.0 + }, + { + "source": "readme", + "target": "readme_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_the_hooks", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L117", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_usage", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L145", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_what_s_in_the_box", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_what_goes_where", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L185", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_why_four_files_plus_github_issues", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L200", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_what_it_is_not", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L216", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_team_wide_use", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L228", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_platform_notes", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L236", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_updating", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L240", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_contributing", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L251", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_privacy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L255", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_license", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L259", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_install", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_the_four_files_plus_the_queue", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_why_this_exists", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "readme_session_continuity", + "target": "readme_the_commands", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L65", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_backlog", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L101", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_learnings", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L105", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_update", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L109", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_help", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L113", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_primer", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_learning", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L79", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_end_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L83", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_doctor", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L93", + "weight": 1.0 + }, + { + "source": "readme_the_commands", + "target": "readme_session_continuity_spike_check", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L97", + "weight": 1.0 + }, + { + "source": "security", + "target": "security_security_policy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "SECURITY.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "security_security_policy", + "target": "security_reporting", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "SECURITY.md", + "source_location": "L20", + "weight": 1.0 + }, + { + "source": "security_security_policy", + "target": "security_design_notes_relevant_to_security_reviewers", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "SECURITY.md", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "security_security_policy", + "target": "security_scope", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "SECURITY.md", + "source_location": "L5", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings", + "target": "session_continuity_learnings_learnings_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_claude_code_plugin_mechanics", + "target": "session_continuity_learnings_2_awk_changelog_range_collapses_on_single_version_files", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L100", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_claude_code_plugin_mechanics", + "target": "session_continuity_learnings_17_worktree_isolation_guard_blocks_any_too_complex_command_not_just_git_c_or_compound_git_chains", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L45", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_claude_code_plugin_mechanics", + "target": "session_continuity_learnings_11_claude_plugin_root_inside_a_bash_fence_in_a_skill_command_file_is_never_resolved_only_the_braced_claude_plugin_root_form_is", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L67", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_claude_code_plugin_mechanics", + "target": "session_continuity_learnings_8_git_c_and_compound_commands_blocked_inside_a_worktree_isolated_session", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L81", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_git_release_mechanics", + "target": "session_continuity_learnings_18_a_subagent_s_done_commit_hash_can_be_a_real_commit_in_the_wrong_repo", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L417", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_git_release_mechanics", + "target": "session_continuity_learnings_15_squash_merging_a_branch_descended_from_an_unpushed_local_commit_orphans_that_commit_and_any_tag_pointing_at_it", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L431", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_21_git_commit_m_cat_eof_eof_triggers_spurious_content_gate_denials_that_a_direct_script_re_test_can_t_reproduce", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L238", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_16_masking_a_gate_s_own_escape_hatch_must_cover_every_raw_content_check_in_that_gate_not_just_the_one_the_bug_report_named", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L279", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_14_commit_time_content_gates_only_see_the_git_index_git_commit_a_pathspec_bypasses_the_scan", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L293", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_12_a_smoke_test_s_own_hermeticity_bug_recurred_twice_in_two_unrelated_tasks_even_after_being_caught_and_fixed_once", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L310", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_13_proven_gate_sh_and_similar_word_boundary_content_gates_re_fire_on_an_edit_even_when_a_valid_escape_hatch_line_already_exists_elsewhere_in_the_same_file", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L324", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_9_removing_a_hook_s_legacy_path_scope_breaks_hermetic_smoke_fixtures_hardcoded_to_that_path_and_a_release_shipped_before_anyone_re_ran_them", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L338", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_7_a_grep_based_gate_cannot_reliably_scan_a_plan_that_documents_the_gate_s_own_syntax", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L353", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "target": "session_continuity_learnings_1_pretooluse_hooks_must_emit_json_to_reach_claude_s_context", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L367", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_symptoms_index", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_slash_command_skill_authoring", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L128", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_hook_scripting_sessionstart_pretooluse", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L236", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_git_release_mechanics", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L415", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_claude_code_plugin_mechanics", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L43", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_security_incidents", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L466", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_anti_patterns_we_were_tempted_by_and_rejected", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L473", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_learnings_session_continuity", + "target": "session_continuity_learnings_checklist_for_a_fresh_dev_env_setup", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L481", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_slash_command_skill_authoring", + "target": "session_continuity_learnings_20_a_per_link_or_about_to_become_true_disjunction_fix_for_one_chained_trigger_doesn_t_generalize_to_the_next_link", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L130", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_slash_command_skill_authoring", + "target": "session_continuity_learnings_19_jq_oniguruma_s_m_flag_means_dot_matches_newline_not_pcre_s_s", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L144", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_slash_command_skill_authoring", + "target": "session_continuity_learnings_10_jq_s_split_n_0_returns_null_on_an_empty_string_crashes_the_next_gsub_in_a_chain", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L158", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_slash_command_skill_authoring", + "target": "session_continuity_learnings_6_stale_path_references_in_slash_command_bodies_survive_plugin_path_migrations", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L172", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_slash_command_skill_authoring", + "target": "session_continuity_learnings_5_superpowers_style_upstream_skills_hardcode_docs_superpowers_specs_plans_and_silently_re_create_deleted_directories", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L186", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_slash_command_skill_authoring", + "target": "session_continuity_learnings_4_init_mode_commits_can_leak_placeholder_tokens_when_the_user_skips_ahead", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L200", + "weight": 1.0 + }, + { + "source": "session_continuity_learnings_slash_command_skill_authoring", + "target": "session_continuity_learnings_3_checklist_style_prose_needs_an_explicit_enumerate_don_t_summarize_rule", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/LEARNINGS.md", + "source_location": "L214", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context", + "target": "session_continuity_project_context_project_context_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_repo_layout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_working_directory", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L33", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_the_packages_modules", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L41", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_test_expectations_these_must_stay_green", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L51", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_end_to_end_check_real_integration", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L55", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_workflow_conventions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L66", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_where_to_look_for_what", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L74", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_ground_rules_how_to_work_here", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L8", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_if_you_get_stuck", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L85", + "weight": 1.0 + }, + { + "source": "session_continuity_project_context_project_context_session_continuity", + "target": "session_continuity_project_context_maintenance_your_responsibility", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/PROJECT_CONTEXT.md", + "source_location": "L95", + "weight": 1.0 + }, + { + "source": "session_continuity_roadmap", + "target": "session_continuity_roadmap_roadmap_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "session_continuity_roadmap_roadmap_session_continuity", + "target": "session_continuity_roadmap_next", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L29", + "weight": 1.0 + }, + { + "source": "session_continuity_roadmap_roadmap_session_continuity", + "target": "session_continuity_roadmap_later", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L38", + "weight": 1.0 + }, + { + "source": "session_continuity_roadmap_roadmap_session_continuity", + "target": "session_continuity_roadmap_now", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/ROADMAP.md", + "source_location": "L9", + "weight": 1.0 + }, + { + "source": "session_continuity_session_primer", + "target": "session_continuity_session_primer_session_primer_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/SESSION_PRIMER.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "session_continuity_session_primer_session_primer_session_continuity", + "target": "session_continuity_session_primer_current_state", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/SESSION_PRIMER.md", + "source_location": "L21", + "weight": 1.0 + }, + { + "source": "session_continuity_session_primer_session_primer_session_continuity", + "target": "session_continuity_session_primer_first_things_first_read_these_before_touching_anything", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": ".session-continuity/SESSION_PRIMER.md", + "source_location": "L9", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_heuristics", + "target": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "target": "skills_session_continuity_heuristics_presentation_context_window_mode_only", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L104", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "target": "skills_session_continuity_heuristics_privacy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "target": "skills_session_continuity_heuristics_heuristic_a_retry_burst", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "target": "skills_session_continuity_heuristics_heuristic_b_revert_reset", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L48", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "target": "skills_session_continuity_heuristics_heuristic_c_error_recurrence", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L71", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_heuristics_learnings_candidate_heuristics_context_window_fallback", + "target": "skills_session_continuity_heuristics_heuristic_d_fix_burst", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/HEURISTICS.md", + "source_location": "L89", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference", + "target": "skills_session_continuity_reference_session_continuity_reference", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference_session_continuity_reference", + "target": "skills_session_continuity_reference_philosophy", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L100", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference_session_continuity_reference", + "target": "skills_session_continuity_reference_what_goes_where_a_decision_tree", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L50", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference_session_continuity_reference", + "target": "skills_session_continuity_reference_customization_guidance", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L70", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference_session_continuity_reference", + "target": "skills_session_continuity_reference_for_team_wide_use", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L79", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference_session_continuity_reference", + "target": "skills_session_continuity_reference_hooks_and_content_gates", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L8", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference_session_continuity_reference", + "target": "skills_session_continuity_reference_red_flags_when_not_to_use", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L88", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference_session_continuity_reference", + "target": "skills_session_continuity_reference_complementary_mechanisms", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L94", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill", + "target": "skills_session_continuity_skill_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L6", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_session_continuity", + "target": "skills_session_continuity_skill_more_detail", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L165", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_session_continuity", + "target": "skills_session_continuity_skill_gate_mechanics_never_chain_git_add_and_git_commit_in_one_call", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L32", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_session_continuity", + "target": "skills_session_continuity_skill_when_to_use_this_skill", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L47", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_session_continuity", + "target": "skills_session_continuity_skill_quick_start_new_project", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L57", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_session_continuity", + "target": "skills_session_continuity_skill_quick_start_existing_project_with_these_files", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L65", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_session_continuity", + "target": "skills_session_continuity_skill_quick_start_existing_primer_not_yet_split", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L73", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_session_continuity", + "target": "skills_session_continuity_skill_the_maintenance_rules_read_this_before_every_commit", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L81", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_the_maintenance_rules_read_this_before_every_commit", + "target": "skills_session_continuity_skill_do_not_commit_the_primer_by_itself", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L112", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_the_maintenance_rules_read_this_before_every_commit", + "target": "skills_session_continuity_skill_on_a_hard_won_bug_add_to_learnings_md", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L143", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill_the_maintenance_rules_read_this_before_every_commit", + "target": "skills_session_continuity_skill_on_every_substantive_commit_refresh_session_primer_md_in_the_same_commit", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L83", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_claude_md_snippet", + "target": "skills_session_continuity_templates_claude_md_snippet_session_continuity", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md", + "source_location": "L8", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings", + "target": "skills_session_continuity_templates_learnings_learnings_project_name", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_layer_1_name", + "target": "skills_session_continuity_templates_learnings_1_entry_title", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L32", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_layer_2_name", + "target": "skills_session_continuity_templates_learnings_2_entry_title", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_learnings_project_name", + "target": "skills_session_continuity_templates_learnings_symptoms_index", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_learnings_project_name", + "target": "skills_session_continuity_templates_learnings_layer_1_name", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L22", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_learnings_project_name", + "target": "skills_session_continuity_templates_learnings_layer_2_name", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L60", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_learnings_project_name", + "target": "skills_session_continuity_templates_learnings_security_incidents", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L70", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_learnings_project_name", + "target": "skills_session_continuity_templates_learnings_anti_patterns_we_were_tempted_by_and_rejected", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L82", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_learnings_learnings_project_name", + "target": "skills_session_continuity_templates_learnings_checklist_for_a_fresh_dev_env_setup", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/LEARNINGS.md", + "source_location": "L92", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context", + "target": "skills_session_continuity_templates_project_context_project_context_project_name", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_repo_layout", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_working_directory", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_the_packages_modules", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_test_expectations_these_must_stay_green", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L42", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_end_to_end_check_real_integration", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_workflow_conventions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L53", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_where_to_look_for_what", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L60", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_if_you_get_stuck", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L66", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_maintenance_your_responsibility", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L79", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_project_context_project_context_project_name", + "target": "skills_session_continuity_templates_project_context_ground_rules_how_to_work_here", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/PROJECT_CONTEXT.md", + "source_location": "L8", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_roadmap", + "target": "skills_session_continuity_templates_roadmap_roadmap_project_name", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_roadmap_roadmap_project_name", + "target": "skills_session_continuity_templates_roadmap_next", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_roadmap_roadmap_project_name", + "target": "skills_session_continuity_templates_roadmap_later", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L17", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_roadmap_roadmap_project_name", + "target": "skills_session_continuity_templates_roadmap_now", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/ROADMAP.md", + "source_location": "L9", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_session_primer", + "target": "skills_session_continuity_templates_session_primer_session_primer_project_name", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L1", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_session_primer_session_primer_project_name", + "target": "skills_session_continuity_templates_session_primer_mid_flight", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_session_primer_session_primer_project_name", + "target": "skills_session_continuity_templates_session_primer_confirm", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L14", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_session_primer_session_primer_project_name", + "target": "skills_session_continuity_templates_session_primer_peers", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_templates_session_primer_session_primer_project_name", + "target": "skills_session_continuity_templates_session_primer_boot_order", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/templates/SESSION_PRIMER.md", + "source_location": "L3", + "weight": 1.0 + }, + { + "source": "hooks_backend_parity_gate", + "target": "hooks_backend_parity_gate_gate_in_scope", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/backend-parity-gate.sh", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "hooks_backend_parity_gate", + "target": "hooks_backend_parity_gate_gate_check", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/backend-parity-gate.sh", + "source_location": "L18", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_gate_in_scope", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L25", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_dvg_deny", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L32", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_dvg_check_duration", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L39", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_dvg_check_count", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L47", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_dvg_check_compare", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L55", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_dvg_check_verbatim", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "hooks_derived_value_gate", + "target": "hooks_derived_value_gate_gate_check", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/derived-value-gate.sh", + "source_location": "L72", + "weight": 1.0 + }, + { + "source": "hooks_evidence_gate", + "target": "hooks_evidence_gate_gate_in_scope", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/evidence-gate.sh", + "source_location": "L12", + "weight": 1.0 + }, + { + "source": "hooks_evidence_gate", + "target": "hooks_evidence_gate_gate_check", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/evidence-gate.sh", + "source_location": "L18", + "weight": 1.0 + }, + { + "source": "hooks_flaky_gate", + "target": "hooks_flaky_gate_gate_in_scope", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/flaky-gate.sh", + "source_location": "L12", + "weight": 1.0 + }, + { + "source": "hooks_flaky_gate", + "target": "hooks_flaky_gate_gate_check", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/flaky-gate.sh", + "source_location": "L17", + "weight": 1.0 + }, + { + "source": "hooks_flaky_gate", + "target": "hooks_flaky_gate_gate_check_file", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/flaky-gate.sh", + "source_location": "L31", + "weight": 1.0 + }, + { + "source": "hooks_lib_backlog_issues", + "target": "hooks_lib_backlog_issues_fail_open", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/backlog-issues.sh", + "source_location": "L35", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract", + "target": "hooks_lib_candidate_extract_json_escape", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L35", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract", + "target": "hooks_lib_candidate_extract_finish", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L39", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract", + "target": "hooks_lib_candidate_extract_emit", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L52", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_extract", + "target": "hooks_lib_candidate_extract_mtime_epoch", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/candidate-extract.sh", + "source_location": "L59", + "weight": 1.0 + }, + { + "source": "hooks_lib_candidate_render", + "target": "hooks_lib_candidate_render_fallback", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/candidate-render.sh", + "source_location": "L29", + "weight": 1.0 + }, + { + "source": "hooks_lib_checklist_assemble", + "target": "hooks_lib_checklist_assemble_fallback", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/checklist-assemble.sh", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_scan_staged", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L107", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_command", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_load", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_is_commit", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L30", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_staged_files", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L36", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_staged_blob", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L42", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_is_scratch", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L46", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_has_escape", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_mask_escape", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_field", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_gate_first_match", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L88", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_json_escape", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L93", + "weight": 1.0 + }, + { + "source": "hooks_lib_gate_common", + "target": "hooks_lib_gate_common_deny", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/gate-common.sh", + "source_location": "L97", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index", + "target": "hooks_lib_learnings_index_die_install", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L40", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index", + "target": "hooks_lib_learnings_index_check_siblings", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L46", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index", + "target": "hooks_lib_learnings_index_count_entries", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L56", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index", + "target": "hooks_lib_learnings_index_report", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L60", + "weight": 1.0 + }, + { + "source": "hooks_lib_learnings_index", + "target": "hooks_lib_learnings_index_reindex", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/learnings-index.sh", + "source_location": "L66", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_log", + "target": "hooks_lib_perf_log_json_escape", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_log", + "target": "hooks_lib_perf_log_write_record", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L42", + "weight": 1.0 + }, + { + "source": "hooks_lib_perf_log", + "target": "hooks_lib_perf_log_resolve_mark_epoch", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/perf-log.sh", + "source_location": "L85", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_detect", + "target": "hooks_lib_primer_detect_die", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L35", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_detect", + "target": "hooks_lib_primer_detect_file_flag", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-detect.sh", + "source_location": "L49", + "weight": 1.0 + }, + { + "source": "hooks_lib_primer_init_derive", + "target": "hooks_lib_primer_init_derive_die", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/primer-init-derive.sh", + "source_location": "L32", + "weight": 1.0 + }, + { + "source": "hooks_lib_render", + "target": "hooks_lib_render_render_update", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/render.sh", + "source_location": "L132", + "weight": 1.0 + }, + { + "source": "hooks_lib_render", + "target": "hooks_lib_render_die_install", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/render.sh", + "source_location": "L31", + "weight": 1.0 + }, + { + "source": "hooks_lib_render", + "target": "hooks_lib_render_check_sibling", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/render.sh", + "source_location": "L36", + "weight": 1.0 + }, + { + "source": "hooks_lib_render", + "target": "hooks_lib_render_render_backlog", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/render.sh", + "source_location": "L44", + "weight": 1.0 + }, + { + "source": "hooks_lib_render", + "target": "hooks_lib_render_render_learnings", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/render.sh", + "source_location": "L54", + "weight": 1.0 + }, + { + "source": "hooks_lib_render", + "target": "hooks_lib_render_render_help", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/render.sh", + "source_location": "L74", + "weight": 1.0 + }, + { + "source": "hooks_lib_require_script", + "target": "hooks_lib_require_script_require_script", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/require-script.sh", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "hooks_lib_resolve_transcript", + "target": "hooks_lib_resolve_transcript_mtime_epoch", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/resolve-transcript.sh", + "source_location": "L26", + "weight": 1.0 + }, + { + "source": "hooks_lib_test_count_rerun", + "target": "hooks_lib_test_count_rerun_to_json", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L120", + "weight": 1.0 + }, + { + "source": "hooks_lib_test_count_rerun", + "target": "hooks_lib_test_count_rerun_die", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L28", + "weight": 1.0 + }, + { + "source": "hooks_lib_test_count_rerun", + "target": "hooks_lib_test_count_rerun_run_once", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/test-count-rerun.sh", + "source_location": "L98", + "weight": 1.0 + }, + { + "source": "hooks_lib_token_overlap", + "target": "hooks_lib_token_overlap_die", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/lib/token-overlap.sh", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "hooks_occurrence_gate", + "target": "hooks_occurrence_gate_gate_in_scope", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/occurrence-gate.sh", + "source_location": "L12", + "weight": 1.0 + }, + { + "source": "hooks_occurrence_gate", + "target": "hooks_occurrence_gate_gate_check", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/occurrence-gate.sh", + "source_location": "L18", + "weight": 1.0 + }, + { + "source": "hooks_proven_gate", + "target": "hooks_proven_gate_gate_in_scope", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/proven-gate.sh", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "hooks_proven_gate", + "target": "hooks_proven_gate_gate_check", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/proven-gate.sh", + "source_location": "L22", + "weight": 1.0 + }, + { + "source": "hooks_smoke_gate", + "target": "hooks_smoke_gate_gate_in_scope", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/smoke-gate.sh", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "hooks_smoke_gate", + "target": "hooks_smoke_gate_gate_check", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/smoke-gate.sh", + "source_location": "L18", + "weight": 1.0 + }, + { + "source": "hooks_version_check", + "target": "hooks_version_check_json_field", + "relation": "defines", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "hooks/version-check.sh", + "source_location": "L90", + "weight": 1.0 + }, + { + "source": "contributing", + "target": "readme", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CONTRIBUTING.md", + "source_location": "L21", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_27_session_continuity_v0_2_public_release", + "target": "meta_superpowers_specs_2026_04_27_session_continuity_v0_2_public_release_design", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-27-session-continuity-v0.2-public-release.md", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "meta_superpowers_plans_2026_04_28_end_session_command_v0_3", + "target": "meta_superpowers_specs_2026_04_28_end_session_command_design", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "meta/superpowers/plans/2026-04-28-end-session-command-v0.3.md", + "source_location": "L13", + "weight": 1.0 + }, + { + "source": "readme", + "target": "privacy", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "README.md", + "source_location": "L257", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_reference", + "target": "skills_session_continuity_templates_claude_md_snippet", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/REFERENCE.md", + "source_location": "L84", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill", + "target": "skills_session_continuity_reference", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L28", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill", + "target": "skills_session_continuity_templates_learnings", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill", + "target": "skills_session_continuity_templates_project_context", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill", + "target": "skills_session_continuity_templates_roadmap", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L63", + "weight": 1.0 + }, + { + "source": "skills_session_continuity_skill", + "target": "skills_session_continuity_templates_session_primer", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "skills/session-continuity/SKILL.md", + "source_location": "L63", + "weight": 1.0 + } + ], + "hyperedges": [], + "built_at_commit": "797ce81db2f53a2b37e0aeda84f9bbef064ac1f2" +} \ No newline at end of file diff --git a/hooks/lib/peer-probes.sh b/hooks/lib/peer-probes.sh new file mode 100755 index 0000000..4eb5939 --- /dev/null +++ b/hooks/lib/peer-probes.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# peer-probes.sh — ENGRIM + GRAPHIFY probes. Always exit 0. +# Usage: peer-probes.sh [<project-dir>] +# Stdout order (locked): ENGRIM line, then GRAPHIFY line. +set -u +DIR="${1:-.}" +ENGRIM_BIN="${ENGRIM_BIN:-engrim}" +TIMEOUT="${PEER_PROBES_TIMEOUT:-2}" + +# ENGRIM — path with / must be -x; bare name uses command -v +if [[ "$ENGRIM_BIN" == */* ]]; then + if [[ ! -x "$ENGRIM_BIN" ]]; then + echo "ENGRIM=missing" + elif timeout "$TIMEOUT" "$ENGRIM_BIN" context -b 200 >/dev/null 2>&1; then + echo "ENGRIM=ok" + else + echo "ENGRIM=error" + fi +elif ! command -v "$ENGRIM_BIN" >/dev/null 2>&1; then + echo "ENGRIM=missing" +elif timeout "$TIMEOUT" "$ENGRIM_BIN" context -b 200 >/dev/null 2>&1; then + echo "ENGRIM=ok" +else + echo "ENGRIM=error" +fi + +# GRAPHIFY +if [[ -s "$DIR/graphify-out/graph.json" ]]; then + echo "GRAPHIFY=ok" +else + echo "GRAPHIFY=missing" +fi +exit 0 diff --git a/hooks/lib/primer-freshness.sh b/hooks/lib/primer-freshness.sh new file mode 100755 index 0000000..ead25d2 --- /dev/null +++ b/hooks/lib/primer-freshness.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# primer-freshness.sh — substantive-change probe since last primer commit. +# Usage: primer-freshness.sh [<project-dir>] +# Stdout: STALE=0|1|? +# Always exit 0. +set -u +DIR="${1:-.}" +PRIMER=".session-continuity/SESSION_PRIMER.md" + +if [[ ! -f "$DIR/$PRIMER" ]]; then + echo "STALE=?" + exit 0 +fi + +primer_tip="$(git -C "$DIR" log -1 --format=%H -- "$PRIMER" 2>/dev/null || true)" +if [[ -z "$primer_tip" ]]; then + echo "STALE=?" + exit 0 +fi + +stale=0 +paths="$(git -C "$DIR" log "${primer_tip}..HEAD" --name-only --pretty=format: 2>/dev/null | sort -u || true)" +while IFS= read -r path; do + [[ -z "$path" ]] && continue + # Ignore anything under the continuity dir (prefix). + [[ "$path" == .session-continuity/* ]] && continue + bn="$(basename "$path")" + # Basename-only ignore list (docs/README.md ignored; src/readme_utils.sh not). + if [[ "$bn" == README* || "$bn" == CHANGELOG* || "$bn" == LICENSE* ]]; then + continue + fi + stale=1 + break +done <<< "$paths" + +echo "STALE=$stale" +exit 0 diff --git a/hooks/lib/primer-validate.sh b/hooks/lib/primer-validate.sh new file mode 100755 index 0000000..61a4532 --- /dev/null +++ b/hooks/lib/primer-validate.sh @@ -0,0 +1,165 @@ +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# primer-validate.sh — hard-template + banlist gate for SESSION_PRIMER.md +# Usage: primer-validate.sh <primer-file> +# Exit 0 if valid; 1 if invalid. Stderr: INVALID: <reason> (all reasons). +set -u + +FILE="${1:-}" +if [[ -z "$FILE" || ! -f "$FILE" ]]; then + echo "INVALID: primer file required (readable path)" >&2 + exit 1 +fi + +# Single awk pass collects reasons (one per line); bash prints INVALID: prefixes. +reasons=$(awk ' +function add(msg) { + if (msg in seen_reason) return + seen_reason[msg] = 1 + n_reasons++ + reasons[n_reasons] = msg +} + +BEGIN { + allowed["Boot order"] = 1 + allowed["Mid-flight"] = 1 + allowed["Confirm"] = 1 + allowed["Peers"] = 1 +} + +{ + lines[NR] = $0 +} + +END { + # --- H1 / ## headings (ignore fenced bodies) ---------------------------- + h1_ok = 0 + h1_total = 0 + in_fence = 0 + for (i = 1; i <= NR; i++) { + if (lines[i] ~ /^```/) { + in_fence = !in_fence + continue + } + if (in_fence) continue + if (lines[i] ~ /^# / && lines[i] !~ /^## /) { + h1_total++ + if (lines[i] ~ /^# Session Primer — /) h1_ok++ + } + if (lines[i] ~ /^## /) { + h = substr(lines[i], 4) + if (!(h in allowed)) + add("unknown heading '\''## " h "'\''") + else + present[h] = 1 + } + } + if (h1_ok != 1 || h1_total != 1) + add("expected exactly one H1 matching '\''^# Session Primer — '\''") + if (!("Boot order" in present)) add("missing heading '\''## Boot order'\''") + if (!("Mid-flight" in present)) add("missing heading '\''## Mid-flight'\''") + if (!("Confirm" in present)) add("missing heading '\''## Confirm'\''") + if (!("Peers" in present)) add("missing heading '\''## Peers'\''") + + # --- Locate first ```bash fence under ## Confirm ------------------------ + in_confirm = 0 + fence_start = 0 + fence_end = 0 + for (i = 1; i <= NR; i++) { + if (lines[i] ~ /^## Confirm$/) { in_confirm = 1; continue } + if (in_confirm && lines[i] ~ /^## /) { in_confirm = 0 } + if (in_confirm && lines[i] ~ /^```bash[[:space:]]*$/ && fence_start == 0) { + fence_start = i + continue + } + if (fence_start > 0 && fence_end == 0 && lines[i] ~ /^```[[:space:]]*$/) { + fence_end = i + break + } + } + + # --- Confirm command count ---------------------------------------------- + cmd_count = 0 + if (fence_start > 0 && fence_end > fence_start) { + for (i = fence_start + 1; i < fence_end; i++) { + line = lines[i] + if (line ~ /^[[:space:]]*$/) continue + if (line ~ /^#/) continue + cmd_count++ + } + } + if (cmd_count > 5) + add("Confirm counted commands (" cmd_count ") exceed 5") + + # --- Line budget ≤80 excluding Confirm fence ---------------------------- + fence_lines = 0 + if (fence_start > 0 && fence_end >= fence_start) + fence_lines = fence_end - fence_start + 1 + budget = NR - fence_lines + if (budget > 80) + add("line budget (" budget ") exceeds 80 excluding Confirm fence") + + # --- Mid-flight bullets ≤5 ---------------------------------------------- + in_mf = 0 + bullets = 0 + for (i = 1; i <= NR; i++) { + if (lines[i] ~ /^## Mid-flight$/) { in_mf = 1; continue } + if (in_mf && lines[i] ~ /^## /) { in_mf = 0 } + if (in_mf && (lines[i] ~ /^ - / || lines[i] ~ /^- /)) bullets++ + } + if (bullets > 5) + add("Mid-flight bullets (" bullets ") exceed 5") + + # --- Banlist: whole-file precise substrings ----------------------------- + for (i = 1; i <= NR; i++) { + if (index(lines[i], "git log --oneline") > 0) + add("banlist: contains '\''git log --oneline'\''") + if (lines[i] ~ /^## Outstanding/) + add("banlist: contains '\''## Outstanding'\''") + if (lines[i] ~ /^## Current state/) + add("banlist: contains '\''## Current state'\''") + } + + # --- Banlist: any fenced block body ------------------------------------- + in_fence = 0 + body = "" + for (i = 1; i <= NR; i++) { + if (lines[i] ~ /^```/) { + if (in_fence) { + if (index(body, "git log") > 0) + add("banlist: fenced block body contains '\''git log'\''") + n = split(body, blines, "\n") + for (j = 1; j <= n; j++) { + if (blines[j] ~ /^git log( |$)/) { + add("banlist: fenced line matching ^git log( |$)") + break + } + } + in_fence = 0 + body = "" + continue + } + in_fence = 1 + body = "" + continue + } + if (in_fence) { + if (body != "") body = body "\n" + body = body lines[i] + } + } + + for (i = 1; i <= n_reasons; i++) + print reasons[i] +} +' "$FILE") + +rc=0 +if [[ -n "$reasons" ]]; then + while IFS= read -r line; do + [[ -n "$line" ]] || continue + echo "INVALID: $line" >&2 + rc=1 + done <<<"$reasons" +fi +exit "$rc" diff --git a/hooks/pre-commit-check.sh b/hooks/pre-commit-check.sh index 14a2b77..7692846 100755 --- a/hooks/pre-commit-check.sh +++ b/hooks/pre-commit-check.sh @@ -90,7 +90,7 @@ fi # non-blocking; additionalContext is what Claude will actually see. # Docs: https://code.claude.com/docs/en/hooks.md#decision-control-with-json-output cat <<EOF -{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","additionalContext":"⚠️ $primer_rel is not staged for this commit, but code files are. Consider \`git add $primer_rel\` if outstanding items or landed commits need an update. Skip if the primer is genuinely unaffected by this change."}} +{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","additionalContext":"⚠️ $primer_rel is not staged for this commit, but code files are. Consider \`git add $primer_rel\` after refreshing Mid-flight and Confirm only — do not grow the file. Skip if Mid-flight/Confirm are genuinely unaffected by this change."}} EOF exit 0 diff --git a/hooks/session-start.sh b/hooks/session-start.sh index e7b7259..84b3fd7 100755 --- a/hooks/session-start.sh +++ b/hooks/session-start.sh @@ -20,8 +20,10 @@ # * `$cwd` is extracted from the JSON payload and only used as an argument # to directory/file existence tests. It is never `eval`ed or passed # unquoted to a shell command. -# * On any unexpected condition (no payload, no cwd, missing primer) we -# exit 0 silently. A hook that crashes would only confuse the user. +# * On any unexpected condition (no payload, no cwd) we exit 0 silently. +# A hook that crashes would only confuse the user. Never exit non-zero. +# * Missing primer → init nudge. Missing peers → hard-stop. Inject-only — +# never writes SESSION_PRIMER.md. set -euo pipefail @@ -49,13 +51,38 @@ fi primer_new="$cwd/.session-continuity/SESSION_PRIMER.md" -if [ -f "$primer_new" ]; then - primer_path=".session-continuity/SESSION_PRIMER.md" - learnings_path=".session-continuity/LEARNINGS.md" -else +if [ ! -f "$primer_new" ]; then + cat <<'EOF' +<system-reminder> +No .session-continuity/SESSION_PRIMER.md. Run /session-continuity:primer to init. Required peers: engrim + graphify-out/graph.json. +</system-reminder> +EOF + script_dir="$(dirname "$0")" + if [ -x "$script_dir/version-check.sh" ]; then + bash "$script_dir/version-check.sh" || true + fi exit 0 fi +primer_path=".session-continuity/SESSION_PRIMER.md" +learnings_path=".session-continuity/LEARNINGS.md" + +# Peer probes (engrim CLI + graphify-out/graph.json). ENGRIM_BIN is read +# from the environment by peer-probes.sh — export it so nested calls inherit. +peers_helper="$(dirname "$0")/lib/peer-probes.sh" +if [ -n "${ENGRIM_BIN:-}" ]; then + export ENGRIM_BIN +fi +if [ -f "$peers_helper" ]; then + peers_out="$(bash "$peers_helper" "$cwd" 2>/dev/null || true)" +else + peers_out="" +fi +engrim_status="$(printf '%s\n' "$peers_out" | sed -n 's/^ENGRIM=//p' | head -1)" +graphify_status="$(printf '%s\n' "$peers_out" | sed -n 's/^GRAPHIFY=//p' | head -1)" +engrim_status="${engrim_status:-missing}" +graphify_status="${graphify_status:-missing}" + # Compute a 4-line status line ("Check mode" output) so the user and # Claude both see at a glance how fresh the primer is. Every probe is # best-effort — any failure falls back to "?" so the reminder still @@ -99,6 +126,31 @@ else outstanding_block="" fi +# Hard-stop when peers are incomplete. Inject-only — never write the primer. +# Optional backlog shortlist still appends after the stop line. +if [ "$engrim_status" != "ok" ] || [ "$graphify_status" != "ok" ]; then + cat <<EOF +<system-reminder> +PEER SETUP INCOMPLETE: engrim and graphify-out/graph.json are required. Do not start feature work until /session-continuity:doctor is green. +${outstanding_block}</system-reminder> +EOF + script_dir="$(dirname "$0")" + if [ -x "$script_dir/version-check.sh" ]; then + bash "$script_dir/version-check.sh" || true + fi + exit 0 +fi + +# Freshness (substantive commits since last primer change). STALE=1 → warn. +freshness_helper="$(dirname "$0")/lib/primer-freshness.sh" +stale_line="" +if [ -f "$freshness_helper" ]; then + freshness_out="$(bash "$freshness_helper" "$cwd" 2>/dev/null || true)" + if printf '%s\n' "$freshness_out" | grep -qx 'STALE=1'; then + stale_line=$'\n⚠️ Primer may be stale — substantive commits landed since the last primer update.\n' + fi +fi + # Inject the reminder into Claude's SessionStart context. `<system-reminder>` # is the convention Claude Code uses for system-injected context that is # treated as non-user-originating guidance. @@ -106,12 +158,14 @@ cat <<EOF <system-reminder> This project has $primer_path. Read it before any work — it's the fastest path to context. Also check $learnings_path if anything surprises you. +Read Mid-flight and Confirm in the primer before starting work. + Primer status (auto): - HEAD: $status_sha - Last primer change: $status_mtime - Backlog: $status_outstanding - Learnings: $status_learnings -${outstanding_block}</system-reminder> +${outstanding_block}${stale_line}</system-reminder> EOF # Weekly freshness check (best-effort, silent on failure). Runs AFTER the diff --git a/meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md b/meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md new file mode 100644 index 0000000..ca65656 --- /dev/null +++ b/meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md @@ -0,0 +1,467 @@ +# Thin hard-template SESSION_PRIMER Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Ship the thin hard-template SESSION_PRIMER contract from `meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md`: validator + peer probes, SessionStart/doctor hard-incomplete on missing engrim/graphify, slim-migrate for fat primers, banlist git-log blocks. + +**Architecture:** Two new `CONTRACT_VERSION=1` helpers (`peer-probes.sh`, `primer-validate.sh`) plus a freshness helper used by doctor/SessionStart. Template and command prose shrink to Mid-flight/Confirm only. SessionStart gains a missing-primer nudge and a peer hard-stop (**inject-only** — never mutates the primer file). Tests are hermetic zsh smokes with injectable `ENGRIM_BIN` and fixture `graphify-out/graph.json`. + +**Tech Stack:** bash, zsh smokes under `meta/superpowers/validation/`, `engrim` CLI (`engrim context`), graphify artifact `graphify-out/graph.json`, existing `require_script` / `primer-status.sh` patterns. + +## Global Constraints + +- Spec: `meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md` (revised post-review). +- Paths: `.session-continuity/SESSION_PRIMER.md`, `LEARNINGS.md`, `PROJECT_CONTEXT.md`, `ROADMAP.md`. +- Graphify probe target is **only** `graphify-out/graph.json` (non-empty file). +- **graph.json policy (locked):** consuming repos **commit** `graphify-out/graph.json` (regenerate via `/graphify` / `graphify` update when code shape changes). Do **not** gitignore it. Fresh clone must probe green without a local graphify rebuild. Dogfood in Task 8 commits the file. +- Engrim probe: `timeout "${PEER_PROBES_TIMEOUT:-2}" "${ENGRIM_BIN:-engrim}" context -b 200` (exit 0 → ok). Injectable `ENGRIM_BIN` for tests (same pattern as `GH_BIN`). +- Validator is the only shape gate. Agent prose may not be the sole enforcement. +- `commands/primer.md` / `commands/doctor.md` / `commands/end-session.md` must call new helpers through `require_script … 1` (same pattern as `primer-detect.sh`), not bare `bash` paths alone. +- Line budget: ≤80 lines **excluding** the Confirm fenced block. +- Confirm count: non-empty, non-`#` lines inside the single `bash` fence under `## Confirm`. +- Freshness: ⚠️ only (substantive commits after last primer touch). Hard-fail = shape + peers. +- Freshness ignore list matches on **basename only** (`$(basename "$path")`): `README*`, `CHANGELOG*`, `LICENSE*`. So `docs/README.md` is ignored; `src/foo.sh` is not. +- SessionStart: missing primer → one-line nudge, exit 0. Primer present + peer fail → hard-stop text. **Never writes** SESSION_PRIMER (Peers status inject-only into the reminder). +- No live MCP / live GitHub / live engrim DB required in CI — mock `ENGRIM_BIN`. +- Plugin version bump: `0.35.0` → `0.36.0` (minor: consuming-primer contract change). +- Product copy: update `PRIVACY.md` + README (one sentence each) that boot expects local engrim + committed `graphify-out/graph.json`. +- Spec/plan artifacts under `meta/superpowers/`, not `docs/`. +- Do not commit unless the user asked; task Commit steps are optional gates. +- Smoke fixtures live **inside each smoke’s `mktemp` tree** (or heredocs). Do **not** add a new `validation/fixtures/` convention. + +## File map + +| File | Role | +|---|---| +| `hooks/lib/peer-probes.sh` | ENGRIM/GRAPHIFY probes; always exit 0 | +| `hooks/lib/primer-validate.sh` | Shape/banlist/caps; exit 0/1 | +| `hooks/lib/primer-freshness.sh` | STALE=0\|1\|?; always exit 0 | +| `hooks/session-start.sh` | Missing-primer nudge; peer hard-stop; freshness line (inject-only) | +| `skills/session-continuity/templates/SESSION_PRIMER.md` | Thin template | +| `skills/session-continuity/templates/PROJECT_CONTEXT.md` | Drop git-log maintenance | +| `skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md` | Boot order + peers | +| `commands/primer.md` | Init/refresh/slim-migrate/check + `require_script` | +| `commands/doctor.md` | Validate + peers + freshness; drop git-log compare | +| `commands/end-session.md` | Thin refresh; no git-log regen | +| `hooks/pre-commit-check.sh` | Reminder text only (Mid-flight/Confirm) | +| `PRIVACY.md` / `README.md` | Peer disclosure sentences | +| `.session-continuity/SESSION_PRIMER.md` | Dogfood slim-migrate | +| `.session-continuity/PROJECT_CONTEXT.md` | Dogfood Maintenance edit | +| `graphify-out/graph.json` | Committed dogfood artifact | +| `CHANGELOG.md` / plugin manifests | `0.36.0` | +| Smokes | new validation scripts listed per task | + +--- + +### Task 1: `peer-probes.sh` + smoke + +**Files:** +- Create: `hooks/lib/peer-probes.sh` +- Create: `meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh` + +**Interfaces:** +- Consumes: project dir (default `.`), `ENGRIM_BIN` (default `engrim`), `PEER_PROBES_TIMEOUT` (default `2`) +- Produces stdout (exactly two lines, order fixed): + - `ENGRIM=ok|missing|error` + - `GRAPHIFY=ok|missing|error` +- Always exit 0 + +- [ ] **Step 1: Write failing smoke** + +`2026-09-09-peer-probes-smoke.zsh` hermetic temp repo (fixtures created in `mktemp`, not a shared fixtures dir): + +1. No `graphify-out/graph.json`, `ENGRIM_BIN=/nonexistent/engrim` → `GRAPHIFY=missing`, `ENGRIM=missing` +2. Create non-empty `graphify-out/graph.json` → `GRAPHIFY=ok` +3. Empty `graphify-out/graph.json` → `GRAPHIFY=missing` +4. Mock `ENGRIM_BIN` script `exit 0` → `ENGRIM=ok` +5. Mock `exit 1` → `ENGRIM=error` +6. Mock `sleep 5` with `PEER_PROBES_TIMEOUT=1` → `ENGRIM=error` (timeout) +7. Always exit 0 from helper even when peers fail + +- [ ] **Step 2: Run smoke; expect fail** (helper missing) + +```bash +zsh meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh +``` + +- [ ] **Step 3: Implement `hooks/lib/peer-probes.sh`** + +```bash +#!/usr/bin/env bash +# CONTRACT_VERSION=1 +# peer-probes.sh — ENGRIM + GRAPHIFY probes. Always exit 0. +# Usage: peer-probes.sh [<project-dir>] +# Stdout order (locked): ENGRIM line, then GRAPHIFY line. +set -u +DIR="${1:-.}" +ENGRIM_BIN="${ENGRIM_BIN:-engrim}" +TIMEOUT="${PEER_PROBES_TIMEOUT:-2}" + +# ENGRIM — path with / must be -x; bare name uses command -v +if [[ "$ENGRIM_BIN" == */* ]]; then + if [[ ! -x "$ENGRIM_BIN" ]]; then + echo "ENGRIM=missing" + elif timeout "$TIMEOUT" "$ENGRIM_BIN" context -b 200 >/dev/null 2>&1; then + echo "ENGRIM=ok" + else + echo "ENGRIM=error" + fi +elif ! command -v "$ENGRIM_BIN" >/dev/null 2>&1; then + echo "ENGRIM=missing" +elif timeout "$TIMEOUT" "$ENGRIM_BIN" context -b 200 >/dev/null 2>&1; then + echo "ENGRIM=ok" +else + echo "ENGRIM=error" +fi + +# GRAPHIFY +if [[ -s "$DIR/graphify-out/graph.json" ]]; then + echo "GRAPHIFY=ok" +else + echo "GRAPHIFY=missing" +fi +exit 0 +``` + +- [ ] **Step 4: Re-run smoke; all pass** + +- [ ] **Step 5: Commit** (only if user asked) + +```bash +git add hooks/lib/peer-probes.sh meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh +git commit -m "feat: peer-probes.sh for engrim + graphify-out/graph.json" +``` + +--- + +### Task 2: `primer-validate.sh` + smoke + +**Files:** +- Create: `hooks/lib/primer-validate.sh` +- Create: `meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh` + +**Interfaces:** +- Consumes: path to primer file (required) +- Exit 0 if valid; non-zero if invalid +- Stderr: one reason per line, prefixed `INVALID: ` + +Checks: +1. Exactly one H1 matching `^# Session Primer — ` +2. `##` headings ⊆ {`Boot order`,`Mid-flight`,`Confirm`,`Peers`} and all four present +3. Lines outside Confirm fence ≤80 (strip the first ` ```bash ` … closing ` ``` ` under Confirm) +4. Mid-flight bullets (`^ - ` or `^- ` under Mid-flight section) ≤5 +5. Confirm counted commands ≤5 +6. Banlist (avoid over-broad `git log -` substring). File matches any of: + - `git log --oneline` + - `git log --oneline -` + - line matching `^git log( |$)` inside a fenced block body + - `## Outstanding` + - `## Current state` (old heading) + - fenced block whose body contains `git log` + +Thin/fat primer bodies are **heredocs inside the smoke** (written into `mktemp`), not checked-in fixture files. + +- [ ] **Step 1: Write failing smoke** (heredoc thin/fat into temp files) + +Cases: +1. Thin primer → exit 0 +2. Fat primer (unknown `##` + git-log fence) → exit ≠0, stderr has `INVALID:` +3. Thin + 6th Mid-flight bullet → fail +4. Confirm fence with 6 command lines → fail +5. Unknown `## History` → fail +6. `#` comment lines in Confirm do not count +7. Confirm line `git log -1 --oneline` inside fence → fail (banlist) +8. Prose mentioning “see git history” without `git log` → still pass + +- [ ] **Step 2: Run smoke; expect fail** (script missing) + +- [ ] **Step 3: Implement `primer-validate.sh`** + +`CONTRACT_VERSION=1`. Use awk/sed for section slicing; keep it bash-only (no python). **Collect all reasons** then exit 1 so doctor can show them. + +- [ ] **Step 4: Re-run smoke; all pass** + +- [ ] **Step 5: Commit** (if asked) + +```bash +git add hooks/lib/primer-validate.sh meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh +git commit -m "feat: primer-validate.sh hard-template + banlist gate" +``` + +--- + +### Task 3: `primer-freshness.sh` + smoke + +**Files:** +- Create: `hooks/lib/primer-freshness.sh` +- Create: `meta/superpowers/validation/2026-09-09-primer-freshness-smoke.zsh` + +**Interfaces:** +- Consumes: project dir +- Stdout: `STALE=0|1|?` +- Always exit 0 + +Algorithm: +1. If no primer file → `STALE=?` +2. `base=$(git -C "$DIR" log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md)` — empty → `STALE=?` +3. For each unique path in `git log ${base}..HEAD --name-only --pretty=format:`: + - Ignore if path is under `.session-continuity/` (prefix match) + - Let `base=$(basename "$path")`; ignore if `base` matches `README*` or `CHANGELOG*` or `LICENSE*` (bash `[[ $base == README* ]]` etc.) + - **Therefore `docs/README.md` is ignored; `src/readme_utils.sh` is not** (basename `readme_utils.sh` ≠ `README*`) + - Any other path → `STALE=1` +4. Else `STALE=0` + +- [ ] **Step 1: Failing smoke** in temp git repo: + 1. Commit thin primer only → `STALE=0` + 2. Commit `src/foo.sh` after primer → `STALE=1` + 3. Commit only `CHANGELOG.md` after primer → `STALE=0` + 4. Commit only `docs/README.md` after primer → `STALE=0` (basename ignore) + 5. Commit only `.session-continuity/LEARNINGS.md` → `STALE=0` + 6. No primer → `STALE=?` + +- [ ] **Step 2: Run; expect fail** + +- [ ] **Step 3: Implement helper** (basename-only ignore as above) + +- [ ] **Step 4: Re-run; pass** + +- [ ] **Step 5: Commit** (if asked) + +--- + +### Task 4: Thin template + copy churn (templates only) + +**Files:** +- Replace: `skills/session-continuity/templates/SESSION_PRIMER.md` +- Modify: `skills/session-continuity/templates/PROJECT_CONTEXT.md` (Maintenance) +- Modify: `skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md` + +- [ ] **Step 1: Write thin SESSION_PRIMER template** exactly per spec (placeholders `{{PROJECT_NAME}}`; Confirm fence with one example `true` command; Mid-flight one placeholder bullet) + +- [ ] **Step 2: Assert template passes validator** + +```bash +sed 's/{{PROJECT_NAME}}/Example/' skills/session-continuity/templates/SESSION_PRIMER.md > /tmp/primer-ex.md +bash hooks/lib/primer-validate.sh /tmp/primer-ex.md +``` + +Expected: exit 0 + +- [ ] **Step 3: Edit PROJECT_CONTEXT template Maintenance** — remove “regenerate git log --oneline -5 block”; replace with “on substantive commits, refresh Mid-flight + Confirm in SESSION_PRIMER.md and stage it with the commit” + +- [ ] **Step 4: Edit CLAUDE_MD_SNIPPET** — boot order lists engrim + graphify as required; point backlog to `/session-continuity:backlog`; note `graphify-out/graph.json` is committed + +- [ ] **Step 5: Commit** (if asked) + +--- + +### Task 5: Wire SessionStart + +**Files:** +- Modify: `hooks/session-start.sh` +- Create: `meta/superpowers/validation/2026-09-09-session-start-peers-smoke.zsh` +- Modify: `meta/superpowers/validation/2026-08-12-session-start-smoke.zsh` (**required** — not optional; missing-primer case must expect the nudge, not silence) + +**Behavior:** +1. Primer missing → print `<system-reminder>` one-liner (exact sentence below). Exit 0. (Replace today's silent exit.) +2. Primer exists → run `peer-probes.sh "$cwd"`. If either ≠ ok → hard-stop reminder (exact sentence below), then optional backlog shortlist. +3. Both ok → existing reminder, plus “read Mid-flight + Confirm”, plus if freshness `STALE=1` append ⚠️ stale line. +4. **Inject-only:** SessionStart never opens SESSION_PRIMER for write; Peers status appears only in the injected reminder text. +5. Never exit non-zero. + +Exact hard-stop sentence (stable for smoke): + +``` +PEER SETUP INCOMPLETE: engrim and graphify-out/graph.json are required. Do not start feature work until /session-continuity:doctor is green. +``` + +Missing-primer sentence: + +``` +No .session-continuity/SESSION_PRIMER.md. Run /session-continuity:primer to init. Required peers: engrim + graphify-out/graph.json. +``` + +- [ ] **Step 1: Write peers smoke** (temp dir as cwd JSON payload). All greps use `grep -qi` / bash `[[ $out == *…* ]]` on lowercased copy where needed: + 1. Empty dir → stdout contains `/session-continuity:primer` + 2. Primer + missing peers → stdout contains exact substring `PEER SETUP INCOMPLETE` **and** `graphify-out/graph.json` **and** `engrim` + 3. Primer + fixture graph + mock `ENGRIM_BIN` ok → stdout contains `SESSION_PRIMER` or `Mid-flight`, and does **not** contain `PEER SETUP INCOMPLETE` + +- [ ] **Step 2: Run; expect fail** + +- [ ] **Step 3: Patch `session-start.sh`** + +Resolve helpers next to script (`$(dirname "$0")/lib/...`). Export/pass `ENGRIM_BIN` through. Keep version-check tail. No writes to `.session-continuity/`. + +- [ ] **Step 4: Update `2026-08-12-session-start-smoke.zsh` missing-primer case** to assert the nudge string (not empty stdout). Re-run new smoke + old smoke; both pass. + +- [ ] **Step 5: Commit** (if asked) + +--- + +### Task 6: Doctor command wiring + +**Files:** +- Modify: `commands/doctor.md` + +- [ ] **Step 1: In Step 1 gather Bash block, add** (via `require_script` gate text in the command prose, same pattern as other helpers): + +```bash +echo "--- primer validate ---" +if [ -f .session-continuity/SESSION_PRIMER.md ] && [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-validate.sh" .session-continuity/SESSION_PRIMER.md \ + && echo "PRIMER_VALIDATE=ok" || echo "PRIMER_VALIDATE=fail" +fi +echo "--- peer probes ---" +if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/peer-probes.sh" . +fi +echo "--- primer freshness ---" +if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then + bash "${CLAUDE_PLUGIN_ROOT}/hooks/lib/primer-freshness.sh" . +fi +``` + +Command prose must `require_script` each of `primer-validate.sh`, `peer-probes.sh`, `primer-freshness.sh` at `CONTRACT_VERSION=1` before relying on their output (mirror existing `primer-status.sh` usage in `commands/primer.md`). + +- [ ] **Step 2: Replace git-log block staleness interpretation** with: + - `PRIMER_VALIDATE=fail` → row ✗ hard fail (shape) + - `ENGRIM`/`GRAPHIFY` ≠ ok → row ✗ hard fail (peers); Notes: commit/rebuild `graphify-out/graph.json`, ensure `engrim` on PATH + - `STALE=1` → ⚠️ only + - Remove “compare embedded git log --oneline -5” instructions + +- [ ] **Step 3: Document install order** in doctor Notes when peers fail: primer → graphify (commit `graph.json`) → engrim → re-doctor + +- [ ] **Step 4: Manual dry-read of doctor.md for contradiction with banlist** (no remaining “git log block” staleness) + +- [ ] **Step 5: Commit** (if asked) + +--- + +### Task 7: Primer + end-session + pre-commit prose + +**Files:** +- Modify: `commands/primer.md` +- Modify: `commands/end-session.md` +- Modify: `hooks/pre-commit-check.sh` (reminder string only) + +**Primer.md changes:** +1. Init copies thin template; print install-order blurb (include: commit `graphify-out/graph.json`); after stage remind doctor stays red until peers exist. +2. Refresh: rewrite only Mid-flight + Confirm (+ Peers status lines in the file are agent-maintained on refresh/slim-migrate only — **not** by SessionStart). **Delete** “Regenerate git log --oneline -5” step. After write, `require_script` + run `primer-validate.sh`; on failure, stop and show stderr. +3. New slim-migrate mode: if validate fails with fat signals OR leftover Outstanding/BACKLOG fossils → rewrite to thin template; agent picks ≤5 Mid-flight bullets; validate before stage. +4. Check mode: status + validate + peer-probes summary (all via `require_script`). +5. Detection table: add `slim_migrate` trigger. + +**end-session.md:** Step 1 = thin Mid-flight/Confirm refresh + re-run Confirm commands + `require_script` validate. Remove git-log regen. + +**pre-commit-check.sh:** reminder text → refresh Mid-flight and Confirm only; do not grow the file. + +- [ ] **Step 1: Patch primer.md** (remove git-log refresh; add `require_script` + validate; add slim-migrate; install order; graph.json commit note) + +- [ ] **Step 2: Patch end-session.md** + +- [ ] **Step 3: Patch pre-commit reminder string** + +- [ ] **Step 4: Grep banlist instructions** + +```bash +rg -n 'git log --oneline -5|Regenerate this block|Outstanding items' commands/primer.md commands/end-session.md hooks/pre-commit-check.sh skills/session-continuity/templates/ +``` + +Expected: no maintenance instructions that regenerate git-log blocks (migration detection mentions of Outstanding OK). + +- [ ] **Step 5: Commit** (if asked) + +--- + +### Task 8: Dogfood + privacy copy + version bump + +**Files:** +- Replace: `.session-continuity/SESSION_PRIMER.md` (slim-migrate) +- Modify: `.session-continuity/PROJECT_CONTEXT.md` Maintenance +- Create/update + **git-add**: `graphify-out/graph.json` (prefer real graphify update; minimal `{"nodes":[],"edges":[]}` only if graphify unavailable — still commit it) +- Ensure: `graphify-out/` is **not** listed in `.gitignore` +- Modify: `PRIVACY.md` — one sentence: session boot expects local engrim memory and a committed `graphify-out/graph.json` +- Modify: `README.md` — one sentence in install/doctor section: engrim + committed graphify graph are required peers +- Modify: `.claude-plugin/plugin.json` → `0.36.0` +- Modify: other version pins if present +- Modify: `CHANGELOG.md` entry for 0.36.0 + +- [ ] **Step 1: Slim-migrate dogfood primer** to hard template; ≤5 Mid-flight bullets reflecting real open work (Issues); Confirm commands that match (e.g. `bash hooks/lib/backlog-issues.sh --count .`, `zsh meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh`) + +- [ ] **Step 2: Validate dogfood primer** + +```bash +bash hooks/lib/primer-validate.sh .session-continuity/SESSION_PRIMER.md +``` + +- [ ] **Step 3: Produce + stage `graphify-out/graph.json`; confirm not gitignored** + +```bash +# prefer: graphify update (or /graphify) from repo root +test -s graphify-out/graph.json +git check-ignore -v graphify-out/graph.json && exit 1 || true +bash hooks/lib/peer-probes.sh . +# expect ENGRIM=ok GRAPHIFY=ok +``` + +- [ ] **Step 4: PRIVACY.md + README peer sentences** + +- [ ] **Step 5: Bump version + CHANGELOG** + +- [ ] **Step 6: Run all new smokes + updated session-start smoke** + +```bash +zsh meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-primer-freshness-smoke.zsh +zsh meta/superpowers/validation/2026-09-09-session-start-peers-smoke.zsh +zsh meta/superpowers/validation/2026-08-12-session-start-smoke.zsh +``` + +- [ ] **Step 7: Commit** (if asked) — include `graphify-out/graph.json` in the release commit set + +--- + +## Spec coverage checklist + +| Spec requirement | Task | +|---|---| +| `peer-probes.sh` graph.json + engrim | 1 | +| Engrim probe before hard-fail wiring | 1 before 5–6 | +| `primer-validate.sh` caps/banlist | 2 | +| Freshness without git-log block (basename ignores) | 3, 6 | +| Thin template | 4 | +| Copy churn templates | 4 | +| SessionStart missing nudge + peer hard-stop (inject-only) | 5 | +| Old session-start smoke updated | 5 | +| Doctor hard-fail shape/peers, ⚠️ stale | 6 | +| `require_script` for new helpers | 6–7 | +| Primer refresh/slim-migrate/check | 7 | +| end-session + pre-commit text | 7 | +| Committed `graphify-out/graph.json` policy | Global + 8 | +| PRIVACY + README peer disclosure | 8 | +| Dogfood + version | 8 | +| Install order documented | 6–7 | +| Confirm counting rule | 2 | +| ≤80 lines excl Confirm fence | 2, 4 | + +## Self-review notes (post caveman-review) + +- Smoke asserts exact `PEER SETUP INCOMPLETE` (not literal `hard-stop`). +- `graph.json` is committed, not gitignored — fresh clone can doctor-green. +- SessionStart never mutates the primer file. +- Freshness ignore is basename-only (`docs/README.md` ignored). +- Banlist avoids bare `git log -` substring false positives. +- Fixtures stay in smoke `mktemp` trees. +- Optional Commit steps honor user git rules. + +--- + +Plan revised after caveman-review. Path: `meta/superpowers/plans/2026-09-09-primer-thin-hard-template.md`. + +**Two execution options:** + +1. **Subagent-Driven (recommended)** — fresh subagent per task, review between tasks +2. **Inline Execution** — execute tasks in this session with checkpoints + +Which approach? diff --git a/meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md b/meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md new file mode 100644 index 0000000..da2cadf --- /dev/null +++ b/meta/superpowers/specs/2026-09-09-primer-thin-hard-template-design.md @@ -0,0 +1,333 @@ +# Design: Thin hard-template SESSION_PRIMER.md (engrim + graphify required) + +Date: 2026-09-09 +Status: approved (brainstorming complete); pending implementation plan +Revised: 2026-09-09 (post caveman-review) + +## Problem + +`.session-continuity/SESSION_PRIMER.md` was the plugin's volatile +session handoff. Three other systems now cover most of what fat primers +grew into: + +| Concern | Owner today | +|---|---| +| Deferred work queue | GitHub Issues labeled `backlog` (`#N`) | +| Durable decisions / facts / feedback / state | engrim | +| Code structure and "how does X work" | graphify (`graphify-out/`) | +| Stable layout / conventions | `PROJECT_CONTEXT.md` | +| Hard-won bug wisdom | `LEARNINGS.md` | + +What remains uniquely valuable is a **clone-local, agent-agnostic, +commit-coupled mid-flight narrative** plus **confirm commands** and a +**boot-order contract**. This repo's live primer (~700 lines) proves the +failure mode: without a hard shape, the file becomes a changelog and +competes with `git log`, Issues, and engrim. + +Dropping the primer entirely would sacrifice: in-repo mid-flight story, +SessionStart boot nudge keyed on primer presence, pre-commit +refresh ritual, and `/session-continuity:primer` + +`/session-continuity:end-session` presence gates. This design keeps +those mechanics and strips the content contract to what still earns +its keep. + +## Goals + +1. Keep `.session-continuity/SESSION_PRIMER.md` as the product file name + (Approach A — no rename to HANDOFF.md). +2. Hard template only: fixed `##` headings, hard line/bullet caps. + Refresh and doctor refuse unknown sections and banlist content via a + **deterministic validator** (not agent judgment alone). +3. Treat **engrim** and **graphify** as required peers. Missing either + at SessionStart or doctor = **hard incomplete** (agent must set up + before other work). +4. Primer owns only mid-flight + confirm + boot order + peer stubs. + Never owns backlog bodies, durable memory, or code maps. +5. Existing fat primers migrate in one `/session-continuity:primer` + slim-migrate shot. +6. Pre-commit nudge and end-session still key off primer presence; + refresh logic only edits allowed sections. +7. Replace today's doctor staleness check (diff primer's embedded + `git log --oneline -5` block) with a freshness rule that does not + require banlist content. + +## Non-goals + +- Renaming the file or `/session-continuity:primer` command. +- Auto-generating Mid-flight from git / engrim / Issues (Approach C). +- Requiring Obsidian, wiki, Neo4j, or other graphify export flags. +- Replacing or deleting `PROJECT_CONTEXT.md`, `LEARNINGS.md`, or + `ROADMAP.md`. +- Changing GitHub Issues backlog identity or + `/session-continuity:backlog`. +- Making `.cursor/RESUME.md` part of the plugin contract (Cursor-local + optional mirror only; name matches the user's Cursor resume note). +- Soft-warn-only peer probes (rejected — hard incomplete). + +## Decisions + +- **Approach A.** Slim the file and probe peers in hooks; keep the name. +- **Peers assumed.** Consuming projects are incomplete without engrim + and graphify. Primer thins hard under that assumption. +- **Hard incomplete.** SessionStart injects a stop instruction; + doctor fails. Not a soft ⚠️-only path. +- **Hard template.** Fixed sections + caps; refresh refuses extras; + doctor fails on unknown headings, oversize, or over-cap bullets. +- **Banlist content** moves out or is deleted on migrate: `git log` + dumps, test-count tables, shipped-history bullets, backlog item + lists, architecture tours, LEARNINGS copies. +- **Probe definitions (v1) — canonical paths:** + - **graphify OK** iff `cwd/graphify-out/graph.json` exists and is + non-empty. That file is the **only** probe target (not + `GRAPH_REPORT.md`, not wiki, not HTML). Building the graph + (`/graphify` / `graphify` update) must produce it. + - **engrim OK** iff a small helper can successfully invoke engrim + context or recall (MCP tool or documented CLI equivalent). Failure + or missing binary/tool = not OK. **Plan must land this probe + before doctor/SessionStart hard-fail wiring** — otherwise CI and + success criteria are untestable. +- **Size gate:** whole file ≤80 lines **excluding** the fenced Confirm + code block. Mid-flight ≤5 bullets. Confirm ≤5 commands (see counting + rule below). Boot order ≤8 lines. +- **Confirm command count:** inside the single ` ```bash ` … ` ``` ` + fence under `## Confirm`, count non-empty lines that do not start + with `#`. Each such line = one command (including lines that use + `&&`). No commands outside that fence. +- **Freshness (replaces git-log block compare):** primer is **stale** + iff there exists at least one commit on `HEAD` after + `git log -1 --format=%H -- .session-continuity/SESSION_PRIMER.md` + whose touched paths are **substantive** (not solely under + `.session-continuity/`, not solely `README*` / `CHANGELOG*` / + `LICENSE*`). Doctor ⚠️ on stale (warn, not hard-fail in v1 — peers + and shape remain hard-fail). Pre-commit nudge already covers the + same gap at commit time. +- **Validator script:** `hooks/lib/primer-validate.sh` is the single + enforcement point. Doctor and `/primer` check/refresh/slim-migrate + must call it. Agent prose may paraphrase; it may not be the only + gate. +- **Install order (documented in init output + README):** + 1. `/session-continuity:primer` (init or slim-migrate) + 2. Build graphify → `graphify-out/graph.json` + 3. Ensure engrim usable + 4. `/session-continuity:doctor` green + Post-init doctor red until steps 2–3 is expected, not a bug. +- **SessionStart when primer missing:** do **not** stay fully silent. + Inject a one-line nudge: run `/session-continuity:primer` to init + (and that engrim + graphify are required peers). Still exit 0; do + not hard-stop feature work solely for a missing primer (unchanged + soft posture for uninstalled repos). Hard-stop applies only when + primer **exists** and a peer probe fails. +- **Copy churn in same change set:** update + `PROJECT_CONTEXT.md` Maintenance (drop “regenerate git log block”), + `skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md`, + `commands/primer.md`, `commands/end-session.md`, + `commands/doctor.md`, and skill/README blurb so nothing still tells + agents to maintain banlist content. + +## Content contract + +Exact shape of the shipped template +(`skills/session-continuity/templates/SESSION_PRIMER.md`): + +```markdown +# Session Primer — {{PROJECT_NAME}} + +## Boot order +1. `.session-continuity/PROJECT_CONTEXT.md` +2. `.session-continuity/LEARNINGS.md` (grep on surprise) +3. engrim context / recall (required) +4. graphify query when the question is about code structure +5. This file — Mid-flight + Confirm +6. `/session-continuity:backlog` for the deferred queue + +## Mid-flight +- … + +## Confirm +```bash +… +``` + +## Peers +- engrim: required — … +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog` +``` + +### Section rules + +| Section | Rule | +|---|---| +| Title | One H1: `# Session Primer — <project>` | +| `## Boot order` | Fixed intent as above; ≤8 lines; not freeform essays | +| `## Mid-flight` | ≤5 bullets; each names open work + pointer (file/PR/`#N`) + optional one-line trap | +| `## Confirm` | ≤5 counted commands (see counting rule); must falsify Mid-flight if they fail | +| `## Peers` | Three stubs only; status lines may be machine-updated | + +**Allowed `##` headings:** exactly `Boot order`, `Mid-flight`, +`Confirm`, `Peers`. Any other `##` → validator fail; refresh refuse. + +**Invariant:** a clone without MCP still has Mid-flight text. A boot +without engrim or graphify is incomplete regardless of primer quality. + +## Runtime + +### New helper: `hooks/lib/peer-probes.sh` + +`CONTRACT_VERSION=1`. Best-effort probes, always exit 0, print +key=value lines: + +``` +ENGRIM=ok|missing|error +GRAPHIFY=ok|missing|error +``` + +- graphify: test `-s "$DIR/graphify-out/graph.json"` only. +- engrim: invoke the agreed probe (implementation plan picks MCP vs + CLI; must match what SessionStart can actually call in Claude Code / + Cursor). Timeout short (~2s). No network beyond what engrim itself + needs for local recall. + +Used by SessionStart and doctor. Single definition — no duplicated +probe prose in command markdown. + +### New helper: `hooks/lib/primer-validate.sh` + +`CONTRACT_VERSION=1`. Exit 0 = valid shape; non-zero = invalid. +Checks: allowed headings only; line budget (≤80 excluding Confirm +fence); Mid-flight ≤5 bullets; Confirm ≤5 counted commands; no +banlist patterns (e.g. fenced `git log`, “Outstanding items”, embedded +`git log --oneline` blocks). Prints machine-readable reasons on +stderr/stdout for doctor to surface. + +Doctor **and** `/primer` refresh/check/slim-migrate invoke this script. +If validate fails, refresh stops and reports the script output — no +“best effort” rewrite past a red validator. + +### SessionStart (`hooks/session-start.sh`) + +When primer **missing:** + +- Inject one-line install nudge (primer + required peers). Exit 0. + No hard-stop. + +When primer **exists:** + +1. Run `peer-probes.sh`. +2. If either peer ≠ `ok`: inject hard-stop reminder — do not start + feature work; set up missing peer(s); doctor will fail. Optionally + still append backlog shortlist after the stop line. +3. If both `ok`: inject read Mid-flight + Confirm; peers OK; backlog + shortlist as today; primer freshness line from `primer-status.sh` + (substantive-commit-since-primer rule above). + +### Doctor + +**Hard-fail** when any of: + +- `primer-validate.sh` non-zero. +- `ENGRIM` or `GRAPHIFY` ≠ `ok`. + +**Warn only (⚠️)** when freshness rule says stale. + +Remove the current “compare embedded `git log --oneline -5` block” +staleness check — that content is banlisted. + +### `/session-continuity:primer` + +- **Init:** copy thin template; fill project name; Peers stubs; + stage. Print install-order blurb (primer → graphify → engrim → + doctor). Doctor remaining red until peers exist is intentional. +- **Refresh:** run `primer-validate.sh` on the proposed result (or + validate current + refuse Mid-flight/Confirm only). Rewrite only + Mid-flight + Confirm (+ Peers status lines). On validator failure, + stop and show reasons. Do not regenerate git-log blocks or + test-count tables. +- **Slim-migrate (new):** when fat primer detected (validator fail + with fat-class reasons, or leftover Outstanding items / inline + backlog), one-shot rewrite to hard template. Agent selects ≤5 + Mid-flight bullets from the old narrative; remaining open work → + file as Issues if needed; rest dropped. Validate before stage. No + dual-write of old sections. +- **Check:** `primer-status.sh` + `primer-validate.sh` + peer probe + summary. + +### Pre-commit nudge + +Unchanged trigger (substantive commit, primer not staged). Reminder +text: refresh Mid-flight and Confirm only; do not grow the file. + +### `/session-continuity:end-session` + +Still requires primer (+ LEARNINGS). Step 1 = thin refresh + re-run +Confirm commands + `primer-validate.sh`. Drop any remaining +instructions that regenerate git-log blocks or treat primer as +changelog. + +## Migration + +Consuming repos with fat primers: + +1. `/session-continuity:primer` (detect → slim-migrate). +2. Review staged thin primer. +3. Ensure `graphify-out/graph.json` exists and engrim is usable. +4. `/session-continuity:doctor` green. + +This plugin repo dogfoods the same migrate when implementing. + +No markdown backlog fallback (already true post-Issues migration). + +## Testing + +| Case | Expect | +|---|---| +| Template fixture | passes `primer-validate.sh`; exact four `##` headings | +| Doctor thin + peers ok | pass | +| Doctor fat / unknown heading / >5 bullets / banlist pattern | fail | +| Doctor missing engrim or graphify | fail | +| Doctor stale (substantive commit after primer) | ⚠️ only | +| SessionStart primer missing | one-line init nudge; exit 0 | +| SessionStart peers missing | hard-stop text in stdout | +| SessionStart peers ok | Mid-flight nudge + backlog shortlist | +| Slim-migrate fixture | output passes validator; ≤5 Mid-flight | +| Confirm counting | `#` comments ignored; `&&` line counts as one | + +Mock engrim probe in tests; do not require live MCP in CI. Graphify +probe uses a fixture `graphify-out/graph.json` in the scratch repo. +Land mockable engrim probe **before** enabling doctor hard-fail in the +same release train. + +## Privacy / product copy + +README, help, doctor, and PRIVACY (if peer data is mentioned): one +sentence each that session boot expects local engrim memory and a +local graphify graph (`graphify-out/graph.json`), and that Mid-flight +text is committed to the repo (same class of disclosure as today for +in-repo continuity files). + +## Open implementation choices (plan, not design) + +Resolved in the implementation plan, not re-litigated here: + +1. Exact engrim probe command/API for Claude Code vs Cursor (**must + be decided in plan Task 1** — blocks doctor hard-fail). +2. Whether Peers status lines are rewritten by SessionStart (file + mutate) or only injected into the reminder (prefer inject-only in + v1 to avoid dirty trees on every boot). +3. Version bump and CHANGELOG framing (likely minor: contract change + for consuming primers). +4. Exact banlist regexes in `primer-validate.sh` (start from: embedded + `git log`, `## Outstanding`, `BACKLOG.md` item dumps, test-count + tables). + +## Success criteria + +- Thin template is the only shipped primer shape. +- Fat content cannot survive `primer-validate.sh` + doctor. +- Cold start with primer present but without engrim or graphify + cannot look "healthy." +- Cold start with no primer gets an init nudge, not silence. +- Mid-flight still answers "what is open right now?" in one screen. +- Backlog, engrim, and graphify are never re-encoded as primer prose. +- No shipped copy still instructs agents to maintain a primer git-log + block. diff --git a/meta/superpowers/validation/2026-08-12-session-start-smoke.zsh b/meta/superpowers/validation/2026-08-12-session-start-smoke.zsh index b984004..6b59549 100755 --- a/meta/superpowers/validation/2026-08-12-session-start-smoke.zsh +++ b/meta/superpowers/validation/2026-08-12-session-start-smoke.zsh @@ -41,7 +41,12 @@ assert_xfail() { payload() { printf '{"cwd":"%s"}' "$1"; } -work="$(mktemp -d)" +# Workspace-local temp: system /tmp denied for nested git config in sandbox. +# macOS mktemp -d ignores TMPDIR unless the template path is under the repo. +tmpdir_root="$repo/.superpowers/sdd/tmp" +mkdir -p "$tmpdir_root" +export TMPDIR="$tmpdir_root" +work="$(mktemp -d "$tmpdir_root/session-start-smoke.XXXXXX")" trap 'rm -rf "$work"' EXIT mock="$work/fake-gh" cat > "$mock" <<'EOF' @@ -55,18 +60,42 @@ EOF chmod +x "$mock" export GH_BIN="$mock" -mk_gh_proj() { +# Peer mocks so backlog cases exercise the peers-ok path (Task 5 hard-stop +# otherwise replaces the normal reminder when engrim/graphify are absent). +mock_engrim="$work/mock-engrim-ok" +cat > "$mock_engrim" <<'EOF' +#!/usr/bin/env bash +exit 0 +EOF +chmod +x "$mock_engrim" +export ENGRIM_BIN="$mock_engrim" + +ensure_peers() { local d="$1" - mkdir -p "$d/.session-continuity" - git -C "$d" init -q + mkdir -p "$d/graphify-out" + print -r -- '{"nodes":[]}' > "$d/graphify-out/graph.json" +} + +# Nested git so probes don't walk up into this plugin repo (fixtures live under it). +init_repo() { + local d="$1" + git -C "$d" -c init.templateDir= init -q git -C "$d" config user.email "test@example.com" git -C "$d" config user.name "Test" +} + +mk_gh_proj() { + local d="$1" + mkdir -p "$d/.session-continuity" + init_repo "$d" git -C "$d" remote add origin "https://github.com/example/repo.git" } # --- Case set 1: github origin + two mocked backlog issues -> shortlist --- -d1="$(mktemp -d)" +d1="$work/case1" +mkdir -p "$d1" mk_gh_proj "$d1" +ensure_peers "$d1" cat > "$d1/.session-continuity/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -82,10 +111,9 @@ assert "1b lists item 1" '1. #12 First item, single line.' "$out1" assert "1c lists item 2 as 2. #15" '2. #15 Second item header text' "$out1" assert "1f includes numbered-list-echo instruction" 'Present these to the user as a numbered list' "$out1" assert_not "1g no migration nudge on a GitHub-backed project" "run /session-continuity:primer now" "$out1" -rm -rf "$d1" -# --- Case set 2: legacy docs/ path is no longer recognized ----------------- -d2="$(mktemp -d)" +# --- Case set 2: no .session-continuity primer → missing-primer nudge ------ +d2="$work/case2" mkdir -p "$d2/docs" cat > "$d2/docs/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -99,12 +127,15 @@ PRIMER touch "$d2/docs/LEARNINGS.md" out2="$(payload "$d2" | bash "$hook")" -assert "2a legacy docs/-only primer produces no reminder" "EMPTY" "$out2" -rm -rf "$d2" +assert "2a missing .session-continuity primer nudges init" \ + "No .session-continuity/SESSION_PRIMER.md. Run /session-continuity:primer to init. Required peers: engrim + graphify-out/graph.json." \ + "$out2" # --- Case set 3: github origin, empty issue list -> clean 0, no shortlist -- -d3="$(mktemp -d)" +d3="$work/case3" +mkdir -p "$d3" mk_gh_proj "$d3" +ensure_peers "$d3" cat > "$d3/.session-continuity/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -119,11 +150,12 @@ assert "3a reports a clean zero, not a malformed value" $'- Backlog: 0\n' "$out3 assert_not "3b no Backlog: header block" $'\nBacklog:\n' "$out3" assert_not "3c no numbered-list-echo instruction" 'Present these to the user as a numbered list' "$out3" assert_not "3d no migration nudge" "run /session-continuity:primer now" "$out3" -rm -rf "$d3" # --- Case set 4: no github origin -> count ?, no shortlist, no nudge ------- -d4="$(mktemp -d)" +d4="$work/case4" mkdir -p "$d4/.session-continuity" +init_repo "$d4" +ensure_peers "$d4" cat > "$d4/.session-continuity/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -135,11 +167,12 @@ out4="$(payload "$d4" | bash "$hook")" assert "4a reports ? when GitHub is unavailable" $'- Backlog: ?\n' "$out4" assert_not "4b no Backlog: header block when GitHub unavailable" $'\nBacklog:\n' "$out4" assert_not "4c no migration nudge (nothing to migrate)" "run /session-continuity:primer now" "$out4" -rm -rf "$d4" # --- Case set 5: old-format inline ## Outstanding items heading ------------ -d5="$(mktemp -d)" +d5="$work/case5" mkdir -p "$d5/.session-continuity" +init_repo "$d5" +ensure_peers "$d5" cat > "$d5/.session-continuity/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -156,11 +189,12 @@ out5="$(payload "$d5" | bash "$hook")" assert "5a migration nudge fires" "run /session-continuity:primer now" "$out5" assert_not "5b old item text never rendered" "Old-format item that must never be echoed" "$out5" assert_not "5c no numbered-list-echo instruction (that's the current-format path)" 'Present these to the user as a numbered list' "$out5" -rm -rf "$d5" # --- Case set 6: empty inline heading still nudges ------------------------- -d6="$(mktemp -d)" +d6="$work/case6" mkdir -p "$d6/.session-continuity" +init_repo "$d6" +ensure_peers "$d6" cat > "$d6/.session-continuity/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -172,11 +206,12 @@ touch "$d6/.session-continuity/LEARNINGS.md" out6="$(payload "$d6" | bash "$hook")" assert "6a migration nudge fires even for an empty inline heading" "run /session-continuity:primer now" "$out6" -rm -rf "$d6" # --- Case set 7: leftover OUTSTANDING_ITEMS.md presence-only trigger ------- -d7="$(mktemp -d)" +d7="$work/case7" mkdir -p "$d7/.session-continuity" +init_repo "$d7" +ensure_peers "$d7" cat > "$d7/.session-continuity/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -193,11 +228,12 @@ out7="$(payload "$d7" | bash "$hook")" assert "7a migration nudge fires on legacy filename presence alone" "run /session-continuity:primer now" "$out7" assert_not "7b legacy file's content is never echoed (presence-only trigger)" "Item that must never be echoed" "$out7" assert_not "7c no numbered-list-echo instruction" 'Present these to the user as a numbered list' "$out7" -rm -rf "$d7" # --- Case set 8: fresh LEARNINGS template still xfail on exemplar headings -- -d8="$(mktemp -d)" +d8="$work/case8" mkdir -p "$d8/.session-continuity" +init_repo "$d8" +ensure_peers "$d8" cat > "$d8/.session-continuity/SESSION_PRIMER.md" <<'PRIMER' # Session Primer @@ -212,7 +248,6 @@ assert_not "8c no numbered-list-echo instruction" 'Present these to the user as assert_not "8d no migration nudge" "run /session-continuity:primer now" "$out8" assert_xfail "8e fresh-install LEARNINGS.md template counts as zero real entries" $'- Learnings: 0\n' "$out8" \ "EXPECTED RED pending Task 4 of meta/superpowers/plans/2026-09-02-fresh-install-count-defects.md: templates/LEARNINGS.md's '### 1. {{ENTRY_TITLE}}' and '### 2. {{ENTRY_TITLE}}' exemplar headings are NOT wrapped in an HTML comment, so count-entries.sh correctly counts them as 2 live headings." -rm -rf "$d8" print "" print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" diff --git a/meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh b/meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh new file mode 100755 index 0000000..ac150f1 --- /dev/null +++ b/meta/superpowers/validation/2026-09-09-peer-probes-smoke.zsh @@ -0,0 +1,109 @@ +#!/usr/bin/env zsh +# peer-probes.sh smoke. Hermetic: temp project dir + mocked ENGRIM_BIN. +# Fixtures live inside mktemp; never touches a shared fixtures dir. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +helper="$repo/hooks/lib/peer-probes.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +# run_probe <dir> [env assignments as NAME=val ...] +# Sets globals: out, last_rc. Must not run inside $() (subshell). +last_rc=0 +out="" +run_probe() { + local dir="$1"; shift + last_rc=0 + out="$(env "$@" bash "$helper" "$dir" 2>/dev/null)" || last_rc=$? +} + +# --- 1: no graph.json, nonexistent ENGRIM_BIN → both missing --------------- +d="$work/case1"; mkdir -p "$d" +run_probe "$d" ENGRIM_BIN=/nonexistent/engrim +engrim_line="$(print -r -- "$out" | sed -n '1p')" +graphify_line="$(print -r -- "$out" | sed -n '2p')" +[[ "$engrim_line" == "ENGRIM=missing" && "$graphify_line" == "GRAPHIFY=missing" ]] \ + && ok "1: no peers -> ENGRIM=missing GRAPHIFY=missing" \ + || bad "1: got '$out' (rc=$last_rc)" +[[ "$last_rc" -eq 0 ]] && ok "1b: exit 0 when both missing" \ + || bad "1b: rc=$last_rc (want 0)" + +# --- 2: non-empty graph.json → GRAPHIFY=ok --------------------------------- +d="$work/case2"; mkdir -p "$d/graphify-out" +print -r -- '{"nodes":[]}' > "$d/graphify-out/graph.json" +run_probe "$d" ENGRIM_BIN=/nonexistent/engrim +graphify_line="$(print -r -- "$out" | sed -n '2p')" +[[ "$graphify_line" == "GRAPHIFY=ok" ]] \ + && ok "2: non-empty graph.json -> GRAPHIFY=ok" \ + || bad "2: got '$out'" + +# --- 3: empty graph.json → GRAPHIFY=missing -------------------------------- +d="$work/case3"; mkdir -p "$d/graphify-out" +: > "$d/graphify-out/graph.json" +run_probe "$d" ENGRIM_BIN=/nonexistent/engrim +graphify_line="$(print -r -- "$out" | sed -n '2p')" +[[ "$graphify_line" == "GRAPHIFY=missing" ]] \ + && ok "3: empty graph.json -> GRAPHIFY=missing" \ + || bad "3: got '$out'" + +# --- 4: mock ENGRIM_BIN exit 0 → ENGRIM=ok ---------------------------------- +d="$work/case4"; mkdir -p "$d" +mock_ok="$work/mock-engrim-ok" +cat > "$mock_ok" <<'EOF' +#!/usr/bin/env bash +exit 0 +EOF +chmod +x "$mock_ok" +run_probe "$d" ENGRIM_BIN="$mock_ok" +engrim_line="$(print -r -- "$out" | sed -n '1p')" +[[ "$engrim_line" == "ENGRIM=ok" ]] \ + && ok "4: mock exit 0 -> ENGRIM=ok" \ + || bad "4: got '$out'" + +# --- 5: mock ENGRIM_BIN exit 1 → ENGRIM=error ------------------------------- +d="$work/case5"; mkdir -p "$d" +mock_fail="$work/mock-engrim-fail" +cat > "$mock_fail" <<'EOF' +#!/usr/bin/env bash +exit 1 +EOF +chmod +x "$mock_fail" +run_probe "$d" ENGRIM_BIN="$mock_fail" +engrim_line="$(print -r -- "$out" | sed -n '1p')" +[[ "$engrim_line" == "ENGRIM=error" ]] \ + && ok "5: mock exit 1 -> ENGRIM=error" \ + || bad "5: got '$out'" +[[ "$last_rc" -eq 0 ]] && ok "5b: exit 0 when ENGRIM=error" \ + || bad "5b: rc=$last_rc (want 0)" + +# --- 6: mock sleep 5 with PEER_PROBES_TIMEOUT=1 → ENGRIM=error ------------- +d="$work/case6"; mkdir -p "$d" +mock_slow="$work/mock-engrim-slow" +cat > "$mock_slow" <<'EOF' +#!/usr/bin/env bash +sleep 5 +exit 0 +EOF +chmod +x "$mock_slow" +run_probe "$d" ENGRIM_BIN="$mock_slow" PEER_PROBES_TIMEOUT=1 +engrim_line="$(print -r -- "$out" | sed -n '1p')" +[[ "$engrim_line" == "ENGRIM=error" ]] \ + && ok "6: timeout -> ENGRIM=error" \ + || bad "6: got '$out'" + +# --- 7: always exit 0 even when peers fail (combined) ---------------------- +d="$work/case7"; mkdir -p "$d" +run_probe "$d" ENGRIM_BIN=/nonexistent/engrim +[[ "$last_rc" -eq 0 ]] && ok "7: helper always exits 0" \ + || bad "7: rc=$last_rc out='$out'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) diff --git a/meta/superpowers/validation/2026-09-09-primer-freshness-smoke.zsh b/meta/superpowers/validation/2026-09-09-primer-freshness-smoke.zsh new file mode 100755 index 0000000..a16df9e --- /dev/null +++ b/meta/superpowers/validation/2026-09-09-primer-freshness-smoke.zsh @@ -0,0 +1,137 @@ +#!/usr/bin/env zsh +# primer-freshness.sh smoke. Hermetic: temp git repos inside mktemp. +# Never touches this repo's working tree. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +helper="$repo/hooks/lib/primer-freshness.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +# Workspace-local temp: system /tmp denied in sandbox; macOS mktemp -d +# ignores TMPDIR unless template is explicit under the repo. +tmpdir_root="$repo/.superpowers/sdd/tmp" +mkdir -p "$tmpdir_root" +export TMPDIR="$tmpdir_root" +work="$(mktemp -d "$tmpdir_root/smoke.XXXXXX")" +trap 'rm -rf "$work"' EXIT + +last_rc=0 +out="" +run_fresh() { + local dir="$1" + last_rc=0 + out="$(bash "$helper" "$dir" 2>/dev/null)" || last_rc=$? +} + +# init_repo <dir> — empty git repo with identity set. +# Empty templateDir: sandbox-safe (no hook template copy). +init_repo() { + local d="$1" + mkdir -p "$d" + git -C "$d" -c init.templateDir= init -q + git -C "$d" config user.email "test@example.com" + git -C "$d" config user.name "Test" +} + +# commit_primer <dir> — thin primer as sole content of a commit +commit_primer() { + local d="$1" + mkdir -p "$d/.session-continuity" + cat > "$d/.session-continuity/SESSION_PRIMER.md" <<'EOF' +# Session Primer — Example + +## Boot order +1. context + +## Mid-flight +- open + +## Confirm +```bash +true +``` + +## Peers +- engrim: required +EOF + git -C "$d" add .session-continuity/SESSION_PRIMER.md + git -C "$d" commit -qm "add primer" +} + +# --- 1: primer only → STALE=0 ---------------------------------------------- +d="$work/case1" +init_repo "$d" +commit_primer "$d" +run_fresh "$d" +[[ "$out" == "STALE=0" && "$last_rc" -eq 0 ]] \ + && ok "1: primer only -> STALE=0 exit 0" \ + || bad "1: got '$out' rc=$last_rc (want STALE=0 rc=0)" + +# --- 2: src/foo.sh after primer → STALE=1 ---------------------------------- +d="$work/case2" +init_repo "$d" +commit_primer "$d" +mkdir -p "$d/src" +print -r -- 'echo hi' > "$d/src/foo.sh" +git -C "$d" add src/foo.sh +git -C "$d" commit -qm "add foo" +run_fresh "$d" +[[ "$out" == "STALE=1" && "$last_rc" -eq 0 ]] \ + && ok "2: src/foo.sh after primer -> STALE=1" \ + || bad "2: got '$out' rc=$last_rc (want STALE=1 rc=0)" + +# --- 3: only CHANGELOG.md after primer → STALE=0 --------------------------- +d="$work/case3" +init_repo "$d" +commit_primer "$d" +print -r -- '# changelog' > "$d/CHANGELOG.md" +git -C "$d" add CHANGELOG.md +git -C "$d" commit -qm "changelog" +run_fresh "$d" +[[ "$out" == "STALE=0" && "$last_rc" -eq 0 ]] \ + && ok "3: CHANGELOG.md only -> STALE=0" \ + || bad "3: got '$out' rc=$last_rc (want STALE=0 rc=0)" + +# --- 4: only docs/README.md after primer → STALE=0 (basename) -------------- +d="$work/case4" +init_repo "$d" +commit_primer "$d" +mkdir -p "$d/docs" +print -r -- '# readme' > "$d/docs/README.md" +git -C "$d" add docs/README.md +git -C "$d" commit -qm "docs readme" +run_fresh "$d" +[[ "$out" == "STALE=0" && "$last_rc" -eq 0 ]] \ + && ok "4: docs/README.md basename ignore -> STALE=0" \ + || bad "4: got '$out' rc=$last_rc (want STALE=0 rc=0)" + +# --- 5: only .session-continuity/LEARNINGS.md → STALE=0 -------------------- +d="$work/case5" +init_repo "$d" +commit_primer "$d" +print -r -- '# learnings' > "$d/.session-continuity/LEARNINGS.md" +git -C "$d" add .session-continuity/LEARNINGS.md +git -C "$d" commit -qm "learnings" +run_fresh "$d" +[[ "$out" == "STALE=0" && "$last_rc" -eq 0 ]] \ + && ok "5: LEARNINGS.md under .session-continuity/ -> STALE=0" \ + || bad "5: got '$out' rc=$last_rc (want STALE=0 rc=0)" + +# --- 6: no primer → STALE=? ------------------------------------------------ +d="$work/case6" +init_repo "$d" +print -r -- 'x' > "$d/README.md" +git -C "$d" add README.md +git -C "$d" commit -qm "init without primer" +run_fresh "$d" +[[ "$out" == "STALE=?" && "$last_rc" -eq 0 ]] \ + && ok "6: no primer -> STALE=? exit 0" \ + || bad "6: got '$out' rc=$last_rc (want STALE=? rc=0)" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) diff --git a/meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh b/meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh new file mode 100755 index 0000000..f6579ee --- /dev/null +++ b/meta/superpowers/validation/2026-09-09-primer-validate-smoke.zsh @@ -0,0 +1,242 @@ +#!/usr/bin/env zsh +# primer-validate.sh smoke. Hermetic: heredoc primers in mktemp. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +helper="$repo/hooks/lib/primer-validate.sh" + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +last_rc=0 +err="" +run_validate() { + local file="$1" + last_rc=0 + err="$(bash "$helper" "$file" 2>&1 >/dev/null)" || last_rc=$? +} + +# Shared thin primer body (valid baseline) +thin_body() { + cat <<'EOF' +# Session Primer — Example + +## Boot order +1. `.session-continuity/PROJECT_CONTEXT.md` +2. `.session-continuity/LEARNINGS.md` (grep on surprise) +3. engrim context / recall (required) +4. graphify query when the question is about code structure +5. This file — Mid-flight + Confirm +6. `/session-continuity:backlog` for the deferred queue + +## Mid-flight +- Example open work — `hooks/lib/foo.sh` — trap: none + +## Confirm +```bash +true +``` + +## Peers +- engrim: required — ok +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog` +EOF +} + +# --- 1: thin primer → exit 0 ------------------------------------------------ +f="$work/thin.md" +thin_body > "$f" +run_validate "$f" +[[ "$last_rc" -eq 0 ]] && ok "1: thin primer -> exit 0" \ + || bad "1: rc=$last_rc err='$err'" + +# --- 2: fat primer (unknown ## + git-log fence) → fail + INVALID: ---------- +f="$work/fat.md" +cat > "$f" <<'EOF' +# Session Primer — Example + +## Boot order +1. context + +## Mid-flight +- open + +## Confirm +```bash +true +``` + +## Peers +- engrim: required + +## Outstanding +```bash +git log --oneline -5 +``` +EOF +run_validate "$f" +[[ "$last_rc" -ne 0 && "$err" == *"INVALID:"* ]] \ + && ok "2: fat primer -> non-zero + INVALID:" \ + || bad "2: rc=$last_rc err='$err'" + +# --- 3: thin + 6th Mid-flight bullet → fail --------------------------------- +f="$work/six-bullets.md" +{ + thin_body | awk ' + /^## Confirm$/ { print "- b2"; print "- b3"; print "- b4"; print "- b5"; print "- b6" } + { print } + ' +} > "$f" +run_validate "$f" +[[ "$last_rc" -ne 0 && "$err" == *"INVALID:"* ]] \ + && ok "3: 6 Mid-flight bullets -> fail" \ + || bad "3: rc=$last_rc err='$err'" + +# --- 4: Confirm fence with 6 command lines → fail --------------------------- +f="$work/six-cmds.md" +cat > "$f" <<'EOF' +# Session Primer — Example + +## Boot order +1. context + +## Mid-flight +- open — `x` — trap: none + +## Confirm +```bash +true +true +true +true +true +true +``` + +## Peers +- engrim: required — ok +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog` +EOF +run_validate "$f" +[[ "$last_rc" -ne 0 && "$err" == *"INVALID:"* ]] \ + && ok "4: 6 Confirm commands -> fail" \ + || bad "4: rc=$last_rc err='$err'" + +# --- 5: unknown ## History → fail ------------------------------------------- +f="$work/history.md" +{ + thin_body + print "" + print "## History" + print -r -- "- old" +} > "$f" +run_validate "$f" +[[ "$last_rc" -ne 0 && "$err" == *"INVALID:"* ]] \ + && ok "5: unknown ## History -> fail" \ + || bad "5: rc=$last_rc err='$err'" + +# --- 6: # comment lines in Confirm do not count ----------------------------- +f="$work/comments.md" +cat > "$f" <<'EOF' +# Session Primer — Example + +## Boot order +1. `.session-continuity/PROJECT_CONTEXT.md` +2. `.session-continuity/LEARNINGS.md` (grep on surprise) +3. engrim context / recall (required) +4. graphify query when the question is about code structure +5. This file — Mid-flight + Confirm +6. `/session-continuity:backlog` for the deferred queue + +## Mid-flight +- Example open work — `hooks/lib/foo.sh` — trap: none + +## Confirm +```bash +# this is a comment +true +# another comment +false && true +# third comment +``` + +## Peers +- engrim: required — ok +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog` +EOF +run_validate "$f" +[[ "$last_rc" -eq 0 ]] && ok "6: Confirm # comments ignored (2 cmds ok)" \ + || bad "6: rc=$last_rc err='$err'" + +# --- 7: Confirm line git log -1 --oneline → banlist fail -------------------- +f="$work/ban-gitlog.md" +cat > "$f" <<'EOF' +# Session Primer — Example + +## Boot order +1. `.session-continuity/PROJECT_CONTEXT.md` +2. `.session-continuity/LEARNINGS.md` (grep on surprise) +3. engrim context / recall (required) +4. graphify query when the question is about code structure +5. This file — Mid-flight + Confirm +6. `/session-continuity:backlog` for the deferred queue + +## Mid-flight +- Example open work — `hooks/lib/foo.sh` — trap: none + +## Confirm +```bash +git log -1 --oneline +``` + +## Peers +- engrim: required — ok +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog` +EOF +run_validate "$f" +[[ "$last_rc" -ne 0 && "$err" == *"INVALID:"* ]] \ + && ok "7: git log -1 --oneline in fence -> banlist fail" \ + || bad "7: rc=$last_rc err='$err'" + +# --- 8: prose "see git history" without git log → pass ---------------------- +f="$work/prose.md" +cat > "$f" <<'EOF' +# Session Primer — Example + +## Boot order +1. `.session-continuity/PROJECT_CONTEXT.md` +2. `.session-continuity/LEARNINGS.md` (grep on surprise) +3. engrim context / recall (required) +4. graphify query when the question is about code structure +5. This file — Mid-flight + Confirm +6. `/session-continuity:backlog` for the deferred queue + +## Mid-flight +- Example open work — see git history for prior attempts — `hooks/lib/foo.sh` — trap: none + +## Confirm +```bash +true +``` + +## Peers +- engrim: required — ok +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog` +EOF +run_validate "$f" +[[ "$last_rc" -eq 0 ]] && ok "8: prose 'see git history' still passes" \ + || bad "8: rc=$last_rc err='$err'" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) diff --git a/meta/superpowers/validation/2026-09-09-session-start-peers-smoke.zsh b/meta/superpowers/validation/2026-09-09-session-start-peers-smoke.zsh new file mode 100755 index 0000000..36c2aec --- /dev/null +++ b/meta/superpowers/validation/2026-09-09-session-start-peers-smoke.zsh @@ -0,0 +1,80 @@ +#!/usr/bin/env zsh +# SessionStart peer hard-stop + missing-primer nudge smoke. +# Hermetic: temp dirs as cwd JSON payload; mocked ENGRIM_BIN + fixture graph. +# Prefer no nested git — peers are mocked without repos. +set -uo pipefail + +here="${0:A:h}" +repo="${here:h:h:h}" +hook="$repo/hooks/session-start.sh" + +export SESSION_CONTINUITY_SKIP_UPDATE_CHECK=1 + +pass=0; fail=0 +ok() { print -P "%F{green}✓%f $1"; (( pass++ )); return 0; } +bad() { print -P "%F{red}✗%f $1"; (( fail++ )); return 0; } + +# Workspace-local temp (sandbox-safe). +tmpdir_root="$repo/.superpowers/sdd/tmp" +mkdir -p "$tmpdir_root" +export TMPDIR="$tmpdir_root" +work="$(mktemp -d "$tmpdir_root/peers-smoke.XXXXXX")" +trap 'rm -rf "$work"' EXIT + +payload() { printf '{"cwd":"%s"}' "$1"; } + +mock_ok="$work/mock-engrim-ok" +cat > "$mock_ok" <<'EOF' +#!/usr/bin/env bash +exit 0 +EOF +chmod +x "$mock_ok" + +# --- 1: empty dir → missing-primer nudge ----------------------------------- +d1="$work/empty" +mkdir -p "$d1" +out1="$(payload "$d1" | bash "$hook")" +[[ "$out1" == *"/session-continuity:primer"* ]] \ + && ok "1: empty dir nudges /session-continuity:primer" \ + || bad "1: expected '/session-continuity:primer' in: $out1" + +# --- 2: primer + missing peers → hard-stop --------------------------------- +d2="$work/no-peers" +mkdir -p "$d2/.session-continuity" +print -r -- '# Session Primer' > "$d2/.session-continuity/SESSION_PRIMER.md" +touch "$d2/.session-continuity/LEARNINGS.md" +# Force engrim missing (do not inherit a real engrim from PATH). +out2="$(payload "$d2" | env ENGRIM_BIN=/nonexistent/engrim bash "$hook")" +[[ "$out2" == *"PEER SETUP INCOMPLETE"* ]] \ + && ok "2a: PEER SETUP INCOMPLETE" \ + || bad "2a: missing PEER SETUP INCOMPLETE in: $out2" +[[ "$out2" == *"graphify-out/graph.json"* ]] \ + && ok "2b: mentions graphify-out/graph.json" \ + || bad "2b: missing graphify path in: $out2" +[[ "$out2" == *"engrim"* ]] \ + && ok "2c: mentions engrim" \ + || bad "2c: missing engrim in: $out2" + +# --- 3: primer + peers ok → normal reminder, no hard-stop ------------------ +d3="$work/peers-ok" +mkdir -p "$d3/.session-continuity" "$d3/graphify-out" +print -r -- '# Session Primer + +## Mid-flight +- open work +' > "$d3/.session-continuity/SESSION_PRIMER.md" +touch "$d3/.session-continuity/LEARNINGS.md" +print -r -- '{"nodes":[]}' > "$d3/graphify-out/graph.json" +out3="$(payload "$d3" | env ENGRIM_BIN="$mock_ok" bash "$hook")" +if [[ "$out3" == *"SESSION_PRIMER"* || "$out3" == *"Mid-flight"* ]]; then + ok "3a: peers ok emits SESSION_PRIMER or Mid-flight" +else + bad "3a: expected SESSION_PRIMER or Mid-flight in: $out3" +fi +[[ "$out3" != *"PEER SETUP INCOMPLETE"* ]] \ + && ok "3b: peers ok has no PEER SETUP INCOMPLETE" \ + || bad "3b: unexpected hard-stop in: $out3" + +print "" +print -P "Result: %F{green}$pass passed%f, %F{red}$fail failed%f" +(( fail == 0 )) diff --git a/skills/session-continuity/SKILL.md b/skills/session-continuity/SKILL.md index e413be7..d1a83ae 100644 --- a/skills/session-continuity/SKILL.md +++ b/skills/session-continuity/SKILL.md @@ -67,7 +67,7 @@ If the `/session-continuity:primer` command is not installed (e.g. this skill wa 1. Read `.session-continuity/SESSION_PRIMER.md` end-to-end. It is designed for this exact moment. 2. Read `.session-continuity/PROJECT_CONTEXT.md` once per session — it changes rarely, so a stale read is unlikely, but skim it if anything about the repo's shape surprises you. 3. Follow the primer's "First things first" list. -4. Before doing ANY work, verify claimed state is still current (the primer can be stale — run its test commands, check `git log`, etc.). +4. Before doing ANY work, verify claimed state is still current (the primer can be stale — run Confirm commands, check `primer-freshness.sh` / peers, etc.). 5. When you commit, update the primer. ## Quick start (existing primer, not yet split) @@ -86,12 +86,15 @@ boundaries before committing. commit even if the primer didn't exist. For every such commit, stage the primer refresh alongside the real diff so they land together. -Sections of the primer most likely to be stale: +Refresh **Mid-flight** and **Confirm** only (thin hard-template). Do +**not** embed or regenerate a `git log` dump — that shape is banlisted; +freshness is `primer-freshness.sh`, peers are `peer-probes.sh`. Keep +Mid-flight ≤5 bullets and Confirm ≤5 counted commands, then run +`primer-validate.sh` before staging. -- **Current state / latest commits.** Regenerate the `git log --oneline -5` block to include the commit you are about to make. -- **Test expectations.** If you added, removed, or skipped tests, bump the count so it matches `<test command>` output. - -Other sections (layout, packages, conventions) drift more slowly but are fair game if the repo shifted. +Stable material (layout, packages, conventions) lives in +`PROJECT_CONTEXT.md` and drifts slowly — touch it only when the repo +shape actually changed. Alongside the primer, also update the GitHub backlog: close issues you just finished (`gh issue close N --reason completed`), file newly-flagged diff --git a/skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md b/skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md index 37176eb..a97c4a1 100644 --- a/skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md +++ b/skills/session-continuity/templates/CLAUDE_MD_SNIPPET.md @@ -7,18 +7,20 @@ Delete this comment block before committing. ## Session continuity -Before touching anything, read `.session-continuity/SESSION_PRIMER.md` -(current state) and `.session-continuity/LEARNINGS.md` (bugs that were -expensive to diagnose — grep it when something surprises you). Read -`.session-continuity/PROJECT_CONTEXT.md` once per session for stable repo -shape, GitHub Issues labeled `backlog` for deferred decisions and -follow-ups, and `.session-continuity/ROADMAP.md` for strategic direction; -primer and ROADMAP change at different rates. +**Boot order (before touching anything):** +1. `.session-continuity/PROJECT_CONTEXT.md` — stable repo shape +2. `.session-continuity/LEARNINGS.md` — grep when something surprises you +3. engrim context / recall (required) +4. graphify query when the question is about code structure (`graphify-out/graph.json` is committed) +5. `.session-continuity/SESSION_PRIMER.md` — Mid-flight + Confirm +6. `/session-continuity:backlog` for deferred decisions and follow-ups +7. `.session-continuity/ROADMAP.md` for strategic direction -**Refresh the primer alongside substantive commits.** Stage the update in -the same commit as the real change — never a primer-only commit (exceptions: -a one-shot catch-up, correcting a factual error, or recording a just-shipped -release). When a bug takes 15+ minutes to diagnose, append a LEARNINGS entry. +**Refresh the primer alongside substantive commits.** Stage Mid-flight + +Confirm updates in the same commit as the real change — never a primer-only +commit (exceptions: a one-shot catch-up, correcting a factual error, or +recording a just-shipped release). When a bug takes 15+ minutes to diagnose, +append a LEARNINGS entry. **Before closing any backlog issue, check it against the actual code** — one grep or read per load-bearing claim, not memory and not a diff --git a/skills/session-continuity/templates/PROJECT_CONTEXT.md b/skills/session-continuity/templates/PROJECT_CONTEXT.md index 6ad46d1..fabb242 100644 --- a/skills/session-continuity/templates/PROJECT_CONTEXT.md +++ b/skills/session-continuity/templates/PROJECT_CONTEXT.md @@ -79,9 +79,9 @@ In order of cost: ## Maintenance (your responsibility) This file changes rarely — only when the project's shape changes (new -module, new convention, moved directory). For the file that changes with -every substantive commit, see `.session-continuity/SESSION_PRIMER.md` and -its own "Primer maintenance" section. +module, new convention, moved directory). On substantive commits, refresh +Mid-flight + Confirm in `.session-continuity/SESSION_PRIMER.md` and stage +it with the commit. When you do edit this file, stage it alongside the change that made the edit necessary — same non-standalone-commit discipline as the primer. diff --git a/skills/session-continuity/templates/SESSION_PRIMER.md b/skills/session-continuity/templates/SESSION_PRIMER.md index e9ae693..14d2776 100644 --- a/skills/session-continuity/templates/SESSION_PRIMER.md +++ b/skills/session-continuity/templates/SESSION_PRIMER.md @@ -1,35 +1,22 @@ # Session Primer — {{PROJECT_NAME}} -You are picking up work on {{PROJECT_NAME}} from a previous session. This -file is the shortest path to what changed recently. For stable repo -context (layout, conventions, modules), read -`.session-continuity/PROJECT_CONTEXT.md` once per session — it changes -rarely. For the backlog of deferred decisions and follow-ups, list GitHub -Issues labeled `backlog` (`/session-continuity:backlog`); for strategic direction, read -`.session-continuity/ROADMAP.md`. - -## First things first (read these before touching anything) - -1. **`.session-continuity/PROJECT_CONTEXT.md`** — stable repo context: - layout, conventions, where to look for what. -2. **`.session-continuity/LEARNINGS.md`** — graveyard of subtle bugs, - grouped by layer. If you hit something weird, grep this file first. -3. **Session memory system** (if the user has one in place) — prior - sessions may have left searchable context. Query before guessing. - -## Current state - -{{CURRENT_STATE_SUMMARY}} - -**Current `git log --oneline -5` (primary branch):** - -``` -{{LATEST_COMMIT_HASH_1}} {{LATEST_COMMIT_SUBJECT_1}} -{{LATEST_COMMIT_HASH_2}} {{LATEST_COMMIT_SUBJECT_2}} -{{LATEST_COMMIT_HASH_3}} {{LATEST_COMMIT_SUBJECT_3}} -{{LATEST_COMMIT_HASH_4}} {{LATEST_COMMIT_SUBJECT_4}} -{{LATEST_COMMIT_HASH_5}} {{LATEST_COMMIT_SUBJECT_5}} +## Boot order +1. `.session-continuity/PROJECT_CONTEXT.md` +2. `.session-continuity/LEARNINGS.md` (grep on surprise) +3. engrim context / recall (required) +4. graphify query when the question is about code structure +5. This file — Mid-flight + Confirm +6. `/session-continuity:backlog` for the deferred queue + +## Mid-flight +- {{MID_FLIGHT_BULLET}} + +## Confirm +```bash +true ``` -Regenerate this block whenever you commit — see -`.session-continuity/PROJECT_CONTEXT.md`'s "Maintenance" section. +## Peers +- engrim: required — status unknown until probed +- graphify: required — `graphify-out/graph.json` +- backlog: GitHub Issues labeled `backlog`