Skip to content

fix(hooks): PreCompact hook must never block auto-compaction#66

Merged
dstolts merged 1 commit into
mainfrom
hotfix/precompact-never-block-auto
May 20, 2026
Merged

fix(hooks): PreCompact hook must never block auto-compaction#66
dstolts merged 1 commit into
mainfrom
hotfix/precompact-never-block-auto

Conversation

@dstolts

@dstolts dstolts commented May 20, 2026

Copy link
Copy Markdown
Owner

Hotfix -- production-breaking

The released PreCompact hook hard-blocks every compaction (exit 2, default block). When Claude Code auto-triggers compaction the context window is full and compaction MUST proceed -- blocking it wedges the session permanently. Every JitNeuro user is currently unable to compact.

Fix

  • source=auto compaction is now ALWAYS warn-only (exit 0) -- can never be blocked
  • source=manual /compact may still pause (exit 2) only when preCompactBehavior=block
  • Default behavior flipped block -> warn (a non-destructive op must not wedge a session by default)
  • Fresh-save check: suppresses the message entirely when /save ran within 10 min

Risk

Low -- hook script only, no app code. Strictly removes the only session-wedging path.

Merge urgency

Hotfix targeting main directly (that is where the broken file is shipped and where installs pull from). Recommend immediate merge.

Follow-ups

## What
Rewrites templates/hooks/pre-compact-save.sh so it never returns exit 2 for
source=auto compaction. Auto-compaction is now always warn-only. Only an
explicit manual /compact may pause, and only when preCompactBehavior=block.
Default behavior flipped from "block" to "warn". Adds a fresh-save check that
suppresses the message entirely when /save ran within the last 10 minutes.

## Why
The released hook hard-blocked every compaction (exit 2, default "block").
When Claude Code auto-triggers compaction the context window is full and
compaction MUST proceed -- blocking it wedges the session permanently. Every
JitNeuro user was unable to compact. Production-breaking.

## Risk
Low. Hook script only, no app code. Strictly safer: removes the only path
that could wedge a session. Manual-compaction blocking is preserved for users
who explicitly opt in via preCompactBehavior=block.

## Test plan
- [x] source=auto + behavior=block: exit 0, compaction proceeds (method: code review of branch)
- [x] source=manual + behavior=block: exit 2, pause (method: code review)
- [x] fresh save marker present: exit 0 silent (method: code review)
- [ ] live: trigger auto-compaction in a session and confirm it proceeds

## Follow-ups
- Phase 2 PR #65 carries an older freshness-only version of this hook; rebase
  #65 onto this fix so it does not regress the hook on merge.
- docs/hooks-guide.md references the old "block default" -- update.
@dstolts dstolts merged commit 38bb64b into main May 20, 2026
1 check failed
dstolts added a commit that referenced this pull request May 20, 2026
## What
Aligns templates/hooks/pre-compact-save.sh on uat with the #66 hotfix
merged to main.

## Why
uat carried the older freshness-only hook version from PR #65, which still
exit-2-blocks auto-compaction. main has the proper hotfix (never blocks auto).
Without this sync the next uat->main promotion would regress the fix.

## Risk
None. Single hook file set equal to the already-merged main version.
dstolts added a commit that referenced this pull request Jun 4, 2026
…ene (#68)

* fix(docs+security): weekly scan W17 -- stale counts + dashboard security (#46)

## What
- CLAUDE.md: correct hook count (4 -> 10 scripts / 9 events) and command count (16 -> 17, add verify)
- docs/commands-reference.md: add missing /help and /verify entries; update lead line from "15 commands" to "17 commands"
- templates/commands/verify.md: sync expected counts (commands 15->17, hook scripts 5->10, hook events 4->9)
- templates/dashboard/server.js: fix 4 security issues from sys-security static review (2026-04-11)

## Why
Weekly W17 scan surfaced #37 (stale CLAUDE.md counts) and #43 (missing /help + /verify in commands-reference.md) still open from prior weeks. Security issues #32-#35 in dashboard/server.js have been open 15 days without fix -- P1 path traversal ships in a published template.

## Security fixes (closes #32, #33, #34, #35)
- #32 P1: path traversal in getSessionContent -- added path.resolve + boundary check before readFileSync
- #33 P2: CORS wildcard + 0.0.0.0 bind -- CORS now reflects localhost origins only; server.listen binds 127.0.0.1
- #34 P3: unauthenticated POST /api/settings -- added schema validation (known keys only, type checks)
- #35 P4: child_process.exec shell string -- replaced exec with spawn(args[]) to eliminate shell injection surface

## Risk
Dashboard server.js changes are localhost-only dev tool. CORS and bind changes are behavior changes: any caller that was relying on external access will now be rejected -- intended, as this is a local tool. Schema validation on /api/settings is additive (rejects unknown keys).

## Test plan
- [x] Manual: node templates/dashboard/server.js -- verify server starts on localhost:9847
- [x] Manual: curl http://127.0.0.1:9847/api/sessions/..%2Fetc%2Fpasswd -- expect 404 (path traversal blocked)
- [x] Manual: verify /help and /verify appear in /help output and commands-reference rendering

* docs: weekly scan W19 -- finish stale command/hook count cleanup

## What
Synced remaining stale component counts in passport and docs to the actual
template inventory (17 commands + 5 shortcuts, 10 hook scripts / 9 hook events):
- CLAUDE.md: hook script template count 4 -> 10
- README.md: "16 commands" -> 17; commands-reference link "15" -> 17
- docs/technical-overview.md: "15 commands + 5 shortcuts" -> 17 (added /help to
  enumeration); "6 hooks" -> "10 hook scripts (9 hook events)" with full list;
  related-docs link "16 commands" -> 17
- docs/comparison-openclaw.md: "6 lifecycle hooks" -> "10 hook scripts / 9 hook
  events"; "12 commands + 5 shortcuts" -> 17
- QUICKSTART.md: "15+ commands, 4 hooks" -> "17 commands, 10 hooks"

## Why
W17 PR #46 fixed CLAUDE.md Key Components, commands-reference.md, and verify.md
but left these strands. W18 scan itemized 3 of them on #37; W19 scan found the
full set (8 strands across 5 files). Mechanical, docs-only.

## Risk
Zero production/template-behavior change. Documentation accuracy only.

## Test plan
- [x] grep for residual stale counts in tracked docs (method: git grep -E '[0-9]+ commands|[0-9]+ hooks?')
- [x] command file count verified 22 = 17 commands + 5 shortcuts (method: ls templates/commands)
- [x] hook script count verified 10 (method: ls templates/hooks/*.sh)

## Related
#37 (passport stale counts -- now fully resolved on uat)

* docs: fix one residual stale hook count in technical-overview.md file tree

W19 scan follow-up: the file-structure diagram still said 'hooks/ (6 lifecycle
hooks)'. Corrected to '10 scripts / 9 hook events' to match the rest of the doc.
Docs-only, no behavior change.

* feat(templates): Step 2 -- notify-jit-knowledge workflow + url-resolver example (#51)

## What
Companion to jit-knowledge PR #33. Ships the two scaffolding artifacts that subscribed repos need to participate in the canonicalization propagation loop.

NEW templates:
- `templates/.github/workflows/notify-jit-knowledge.yml` -- workflow that fires on push to repo's default branch when `.jitneuro/{engrams,bundles,rules,cognition}/**` changes; posts repository_dispatch event to dstolts/jit-knowledge to trigger INDEX.md refresh
- `templates/url-resolver.example.md` -- per-machine `GitHub URL -> local filesystem path` lookup file; consumers read INDEX.md, lookup URL here, load from local clone (fallback to raw.githubusercontent.com)

## Why
Plan v2.1 server-side propagation needs two cooperating workflows:
- Source-side: notify-jit-knowledge.yml in each subscribed repo (this PR ships the TEMPLATE)
- Sink-side: refresh-index.yml in jit-knowledge (shipped in jit-knowledge PR #33)

The notify workflow uses `$default-branch` so it works on repos with main OR uat as default. Owner directive 2026-05-11: uat-first PR-to-main for repos like dash-api / CoWork that default to uat.

## Risk
Templates only. Live install happens per-repo as each enters the subscribed list. Each repo's first install is the Step 3 pilot for dash-api; rollout to clean repos in Step 4.

## Test plan
- [x] Workflow YAML syntactically valid (method: yamllint via Python parser; will validate live when dash-api installs it)
- [x] $default-branch trigger pattern documented as GitHub-supported
- [x] Secret JIT_KNOWLEDGE_DISPATCH_TOKEN already distributed to 7 subscribed repos 2026-05-11
- [x] url-resolver.example.md table matches the 7 subscribed repos + Owner's other clones
- [ ] First install on dash-api (Step 3 pilot) -- verify dispatch fires and reaches jit-knowledge

## Follow-ups
- Step 3: install notify-jit-knowledge.yml in dash-api/.github/workflows/ alongside the first engram migration; verify end-to-end loop fires
- Hub.md tasks #14-17: jitneuro `.knowledge/` placeholder + other template work post-migration stabilization

## Related
- jit-knowledge PR #33 (refresh-index.yml + rebuild-index.py + subscribed-repos.json)
- plan v2.1 (PR #31 merged)
- token distribution: jit-knowledge/projects/dispatch-token-setup.md

* consolidate(template): notify-jit-knowledge uses JITAI_OPENCLAW_PROD secret (#52)

Per Owner directive 2026-05-12: stop the token sprawl. jitai-openclaw-prod is the existing PAT scoped to OC-touchable repos -- exactly the subscribed-repos list. Updating template to reference the consolidated secret name across all subscribed repos. Companion to jit-knowledge PR #35 + dash-api PR #91 update.

## Why
- Consolidates to one PAT for all canonical-knowledge propagation
- Eliminates JIT_KNOWLEDGE_DISPATCH_TOKEN (now slated for decommission)
- Future expansion: add new repos to jitai-openclaw-prod's access list, install this template, done

## Risk
Template only. No live workflow runs from this PR. Each repo that installs the template inherits the new secret name. dash-api PR #91 amendment + future subscribed repos all reference the consolidated secret.

## Test plan
- [x] Template YAML valid
- [x] Secret name matches consolidation plan
- [ ] First production validation: dash-api PR #91 merge

## Related
- jit-knowledge PR #35 (jk workflow + setup doc consolidation)
- dash-api PR #91 amendment (Step 3 pilot, install template)
- jit-knowledge/projects/dispatch-token-setup.md (canonical setup + decommission instructions)

* feat: subscribe jitneuro to jit-knowledge canonical sync (#53) (#54)

## What
- Adds `.jitneuro/engrams/context.md` -- canonical engram migrated from
  `C:/Users/dstolts/Code/.claude/engrams/jitneuro-context.md` (Step 4 of
  jit-knowledge-as-single-source-of-truth-plan.md). Reshaped to dense
  AI-useful sections, updated stale D:/Code paths to C:/Users/dstolts/Code,
  added jit-knowledge subscription section, skills table, not-this list.
- Adds `.github/workflows/notify-jit-knowledge.yml` -- repository_dispatch
  trigger so jit-knowledge regenerates INDEX.md on every `.jitneuro/**`
  change on main. Uses JITAI_OPENCLAW_PROD secret (already provisioned).

## Why
Step 4 item 5 of jit-knowledge-as-single-source-of-truth-plan.md. Canonical
engrams must live in-repo under .jitneuro/engrams/context.md so jit-knowledge
can index them and consuming agent systems load them from a single source.

## Risk
Zero production code changes. Two new files only. GH Action fires on push to
main -- benign if JITAI_OPENCLAW_PROD secret is valid (already provisioned).

## Test plan
- [x] Files staged and committed (method: git status confirms 2 new files)
- [ ] PR merge triggers notify-jit-knowledge.yml (method: GH Actions run log after merge)

## Follow-ups
- Source engram at C:/Users/dstolts/Code/.claude/engrams/jitneuro-context.md
  can be soft-deprecated once jit-knowledge INDEX.md picks up this canonical file
- Update context-manifest.md routing to reference canonical path (separate PR)

* retire(templates): replace routing templates with INDEX.md pointer docs (#55)

* feat: subscribe jitneuro to jit-knowledge canonical sync

## What
- Adds `.jitneuro/engrams/context.md` -- canonical engram migrated from
  `C:/Users/dstolts/Code/.claude/engrams/jitneuro-context.md` (Step 4 of
  jit-knowledge-as-single-source-of-truth-plan.md). Reshaped to dense
  AI-useful sections, updated stale D:/Code paths to C:/Users/dstolts/Code,
  added jit-knowledge subscription section, skills table, not-this list.
- Adds `.github/workflows/notify-jit-knowledge.yml` -- repository_dispatch
  trigger so jit-knowledge regenerates INDEX.md on every `.jitneuro/**`
  change on main. Uses JITAI_OPENCLAW_PROD secret (already provisioned).

## Why
Step 4 item 5 of jit-knowledge-as-single-source-of-truth-plan.md. Canonical
engrams must live in-repo under .jitneuro/engrams/context.md so jit-knowledge
can index them and consuming agent systems load them from a single source.

## Risk
Zero production code changes. Two new files only. GH Action fires on push to
main -- benign if JITAI_OPENCLAW_PROD secret is valid (already provisioned).

## Test plan
- [x] Files staged and committed (method: git status confirms 2 new files)
- [ ] PR merge triggers notify-jit-knowledge.yml (method: GH Actions run log after merge)

## Follow-ups
- Source engram at C:/Users/dstolts/Code/.claude/engrams/jitneuro-context.md
  can be soft-deprecated once jit-knowledge INDEX.md picks up this canonical file
- Update context-manifest.md routing to reference canonical path (separate PR)

* retire(templates): replace routing templates with INDEX.md pointer docs

## What
Replace jitneuro template files that propagated the parallel-router pattern with
pointer docs explaining the new pattern (INDEX.md as single routing source).

- templates/context-manifest.md: replaced with pointer doc + deprecation notice
- templates/.archive/context-manifest.md: archived original
- templates/rules/routing-weights.md: replaced with pointer doc + deprecation notice
- templates/.archive/rules-routing-weights.md: archived original

## Why
Step 6 Layer B sweep (jit-knowledge-as-single-source-of-truth plan v2.1).
The jitneuro templates ship these files to new repos on install. If the templates
teach the old parallel-router pattern, every new repo created will need remediation.
Replacing templates now prevents propagation of the retired pattern.

## Risk
Low. New repos using these templates will see pointer docs instead of routing tables.
Existing repos already installed are not affected (their local files unchanged).

## Test plan
- [x] templates/context-manifest.md contains pointer language, not routing tables (method: Read tool)
- [x] templates/rules/routing-weights.md contains pointer language, not routing tables (method: Read tool)
- [x] Archived originals exist in templates/.archive/ (method: Read tool)

## Follow-ups
- jitneuro docs (concepts.md, setup-guide.md, memory-maintenance.md, cursor-and-cross-vendor.md) still teach old pattern: open issue
- install.ps1 and install.sh still seed routing files: open issue (Hub.md tasks #14-17)

## Related
- jit-knowledge PR feat/step6-layer-b-sweep (companion changes)
- jit-knowledge PR #61 (Layer C governance + CI lint)
- projects/step6-layer-b-sweep-report.md in jit-knowledge

* docs(step6): teach INDEX.md single-source routing in jitneuro docs and install scripts (#56)

* feat: subscribe jitneuro to jit-knowledge canonical sync (#53)

## What
- Adds `.jitneuro/engrams/context.md` -- canonical engram migrated from
  `C:/Users/dstolts/Code/.claude/engrams/jitneuro-context.md` (Step 4 of
  jit-knowledge-as-single-source-of-truth-plan.md). Reshaped to dense
  AI-useful sections, updated stale D:/Code paths to C:/Users/dstolts/Code,
  added jit-knowledge subscription section, skills table, not-this list.
- Adds `.github/workflows/notify-jit-knowledge.yml` -- repository_dispatch
  trigger so jit-knowledge regenerates INDEX.md on every `.jitneuro/**`
  change on main. Uses JITAI_OPENCLAW_PROD secret (already provisioned).

## Why
Step 4 item 5 of jit-knowledge-as-single-source-of-truth-plan.md. Canonical
engrams must live in-repo under .jitneuro/engrams/context.md so jit-knowledge
can index them and consuming agent systems load them from a single source.

## Risk
Zero production code changes. Two new files only. GH Action fires on push to
main -- benign if JITAI_OPENCLAW_PROD secret is valid (already provisioned).

## Test plan
- [x] Files staged and committed (method: git status confirms 2 new files)
- [ ] PR merge triggers notify-jit-knowledge.yml (method: GH Actions run log after merge)

## Follow-ups
- Source engram at C:/Users/dstolts/Code/.claude/engrams/jitneuro-context.md
  can be soft-deprecated once jit-knowledge INDEX.md picks up this canonical file
- Update context-manifest.md routing to reference canonical path (separate PR)

* retire(templates): replace routing templates with INDEX.md pointer docs

## What
Replace jitneuro template files that propagated the parallel-router pattern with
pointer docs explaining the new pattern (INDEX.md as single routing source).

- templates/context-manifest.md: replaced with pointer doc + deprecation notice
- templates/.archive/context-manifest.md: archived original
- templates/rules/routing-weights.md: replaced with pointer doc + deprecation notice
- templates/.archive/rules-routing-weights.md: archived original

## Why
Step 6 Layer B sweep (jit-knowledge-as-single-source-of-truth plan v2.1).
The jitneuro templates ship these files to new repos on install. If the templates
teach the old parallel-router pattern, every new repo created will need remediation.
Replacing templates now prevents propagation of the retired pattern.

## Risk
Low. New repos using these templates will see pointer docs instead of routing tables.
Existing repos already installed are not affected (their local files unchanged).

## Test plan
- [x] templates/context-manifest.md contains pointer language, not routing tables (method: Read tool)
- [x] templates/rules/routing-weights.md contains pointer language, not routing tables (method: Read tool)
- [x] Archived originals exist in templates/.archive/ (method: Read tool)

## Follow-ups
- jitneuro docs (concepts.md, setup-guide.md, memory-maintenance.md, cursor-and-cross-vendor.md) still teach old pattern: open issue
- install.ps1 and install.sh still seed routing files: open issue (Hub.md tasks #14-17)

## Related
- jit-knowledge PR feat/step6-layer-b-sweep (companion changes)
- jit-knowledge PR #61 (Layer C governance + CI lint)
- projects/step6-layer-b-sweep-report.md in jit-knowledge

* docs(step6): teach INDEX.md single-source routing in docs and install scripts

## What
- Replace parallel-router teaching in 4 flagged docs (concepts.md, setup-guide.md,
  memory-maintenance.md, cursor-and-cross-vendor.md) + 7 adjacent docs
- Update 8 command templates (bundle, health, enterprise, onboard, orchestrate, session,
  verify, CLAUDE-brainstem) to reference INDEX.md routing instead of context-manifest/MEMORY.md
- Update install.ps1 and install.sh: stop seeding context-manifest.md; detect legacy installs
  and emit a retirement notice pointing to cleanup scripts; scaffold url-resolver.md
- Add templates/url-resolver.md: machine-specific GitHub URL -> local clone map template
- Cherry-picked template pointer docs from feat/step6-layer-b-sweep-routing (commit 0defeaf)
  since that branch has not yet merged to main

## Why
Step 6 Layer B sweep follow-up. The four docs still taught the retired pattern:
routing-weights.md + context-manifest.md as local routing surfaces. New installs following
those docs would have created routing files that routing-single-source.md prohibits.
Install scripts actively seeded context-manifest.md on fresh installs. Both propagation
vectors close with this commit.

## Risk
Zero production code changes. Docs and templates only. Existing installs are not modified
(install scripts detect and warn, not overwrite). url-resolver.md is a new opt-in file.

## Test plan
- [x] install.sh: syntax OK (method: bash -n)
- [x] install.ps1: syntax OK (method: PowerShell parser AST check)
- [x] Final grep: no remaining actionable hits for routing-weights/context-manifest in docs or templates
  outside of: archived files, tombstone pointer docs, historical release notes, and the
  routing-vs-semantic-memory conceptual doc (which has a retraction note at top)

## Follow-ups
- Open PR and merge to main
- Merge feat/step6-layer-b-sweep-routing to main (jitneuro PR #55 equivalent work included here)

## Related
- jit-knowledge PR #61 (Layer C: routing-single-source.md + CI lint)
- jit-knowledge PR #62 (Layer D: cleanup-old-routing scripts)
- jit-knowledge PR #63 (Layer B sweep -- archived/tombstoned parallel surfaces)

* chore(docs): retire routing-vs-semantic-memory.md (Step 6 cleanup) (#57)

## What
Deletes docs/routing-vs-semantic-memory.md. The doc discussed
routing-weights as a design philosophy, which Step 6 retired.

## Why
PR #56 added a retraction note at the top of the doc but left the
body intact. The body teaches a model that no longer applies; future
readers will be confused. The semantic-memory concept (engrams as
durable identity, bundles as on-demand domain knowledge) is now
covered by the architecture and concepts docs without the routing-
weights framing.

## Risk
NONE. Doc-only deletion. The historical model is preserved in git
history if anyone needs to reference it.

## Test plan
- [x] No other doc cross-references this file (method: ripgrep across
  jitneuro repo for "routing-vs-semantic-memory")
- [x] No template or install script references this file (method:
  same ripgrep)

## Related
- PR #56 (Step 6 docs sync; added retraction note that this PR
  completes)
- jit-knowledge PR #61 (Step 6 governance lock)

* chore(ci): retire Paperclip Dispatch workflow (broken; replacement to follow) (#58)

## What
Removes .github/workflows/paperclip-dispatch.yml.

## Why
Per jit-knowledge/projects/oc-onboarding-followups.md Section 4: Paperclip is
winding down. The dispatch workflow POSTs to a Paperclip API that no longer
responds, failing every PR with curl exit code 22. Removing it gives clean CI
signal on PRs immediately.

## Replacement plan
A working PR-event auto-trigger is still needed. This PR is removal-only; the
replacement (self-hosted GitHub runner on Mac-mini invoking local Claude Code)
will follow as a separate PR.

## Risk
LOW. Workflow had no successful run path; removing it removes only failure noise.

* docs(jit-knowledge): remove local paths from jitneuro engram (#59)

* chore(paths): update absolute path references after workspace reorg (#61)

* fix(install): register Claude Code hooks as bare paths, not shell-prefixed (#62)

## What
install.sh and install.ps1 write each hook `command` as a bare script path.
Previously install.sh emitted `bash "<path>"` and install.ps1 emitted
`"<bash-exe>" "<path>"`.

## Why
Claude Code runs each hook `command` through its own shell. A shell prefix
makes that shell try to execute bash as bash's own script argument, failing
every PreToolUse / PostToolUse / SessionStart / SessionEnd / PreCompact hook
with "bash.exe: bash.exe: cannot execute binary file". No hook runs.

## Risk
Low. Touches only the two installers' hook-command construction. Hook script
contents, hook events, matchers, and timeouts are unchanged. Re-running an
installer re-registers hooks with the corrected command.

## Test plan
- [x] install.sh syntax clean (method: bash -n)
- [x] install.ps1 parses (method: PowerShell Parser::ParseFile)
- [x] every generated command is a bare path, no bash/bash.exe prefix (method: grep)

* feat(recursive-improvement): Phase 2 -- WS4 save-router, WS5 session-end trigger + PreCompact fix, WS6 cross-repo rollup agent (#65)

## What
- WS4: add save-router classification (destination + risk tier T1/T2/T3) to /learn write phase;
  Agent B appends one-line echo to append-only improvement-changes.log.md after each approved write;
  log format: ISO-timestamp | type | summary | destination | session
- WS5: fix PreCompact hook -- stateless block on every compaction prevented compaction even after
  a recent /save; now reads .last-save-timestamp marker and exits 0 (allows silently) when save
  is fresh within 10-minute threshold; /session save now writes the timestamp marker via Bash
- WS5: add session-end-lessons-flush.sh hook -- flushes Hub.md ## Lessons Learned to durable
  lessons-pending.md on SessionEnd so lessons survive context reset without requiring /learn to run first
- WS5: add learn-runner scheduled agent entry (disabled by default, 8h interval, /learn q)
- WS6: add cross-repo-rollup CHARTER.md with full agent prompt -- weekly scan of all repo
  .jitneuro/ dirs + changes-log + lessons-pending for recurring patterns, skill gaps, stale knowledge;
  proposes jit-knowledge promotions in batch with idempotency via content hash, skip-if-no-change,
  Haiku parallel leaf scanning, one manifest rebuild per batch; rollupAutoPR flag (default false)
- Wire session-end-lessons-flush.sh into jitneuro.json hookEvents (SessionEnd)
- Add learn-runner and cross-repo-rollup to jitneuro.json scheduledAgents

## Why
Phase 1 (PR #183) shipped WS1+WS2+WS3. Phase 2 closes the save loop: WS4 routes writes with
explicit destinations and a machine-readable change-record; WS5 ensures no lesson is lost at
session end and compaction no longer blocks unnecessarily after a recent save; WS6 provides the
cross-repo aggregate view needed to identify truly canonical patterns for jit-knowledge promotion.

## Risk
Knowledge / config / shell changes only. No application code. The PreCompact fix is behavioral:
compaction now proceeds silently after a fresh save rather than blocking -- less disruptive, not
less safe. New hook script exits 0 on any error (set +e throughout) so it cannot break a session.

## Test plan
- [x] learn.md: Phase 2 table now includes Destination + Tier columns (method: file review)
- [x] learn.md: Agent B prompt includes changes-log append step (method: file review)
- [x] pre-compact-save.sh: freshness check reads marker, exits 0 when fresh (method: code review)
- [x] session.md: save step 6/7 writes .last-save-timestamp via Bash (method: file review)
- [x] session-end-lessons-flush.sh: reads Hub.md, appends unprocessed lessons (method: code review)
- [x] jitneuro.json: SessionEnd entry for lessons-flush hook present (method: file review)
- [x] jitneuro.json: learn-runner + cross-repo-rollup scheduledAgents entries present (method: file review)
- [x] CHARTER.md: all 6 steps documented, idempotency + skip-if-no-change + Haiku batching wired (method: file review)

## Follow-ups
- Phase 3: WS7 Daily Improvement Scout, WS8 Improvement Changes Dashboard
- Enable learn-runner in jitneuro.json when session has active learnings
- Enable cross-repo-rollup when first cross-repo scan is desired
- Add rollupAutoPR: true after Owner validates first manual rollup proposal

* fix(hooks): sync PreCompact auto-compaction hotfix onto uat

## What
Aligns templates/hooks/pre-compact-save.sh on uat with the #66 hotfix
merged to main.

## Why
uat carried the older freshness-only hook version from PR #65, which still
exit-2-blocks auto-compaction. main has the proper hotfix (never blocks auto).
Without this sync the next uat->main promotion would regress the fix.

## Risk
None. Single hook file set equal to the already-merged main version.

* fix(install): PowerShell installer installs all framework rules (parity with install.sh)

## What
install.ps1 only copied a single scoped-rule-example.md when the rules dir was
empty. It now installs ALL framework rule templates with the same semantics as
install.sh: skip user-DISABLED rules, update only on content diff, install new.

## Why
Windows/PowerShell adopters were getting 1 of 40 framework rules -- the DOE
behavioral ruleset was effectively absent on Windows installs. bash installs the
full set; PowerShell diverged. This restores parity.

## Risk
Installer-only; no framework content changed. install.ps1 parses clean
(method: PowerShell AST ParseFile, 0 errors). Rule count verified: 40 templates.
Not E2E-run against a live ~/.claude (would mutate real settings).

## Test plan
- [x] install.ps1 parses clean (method: [Parser]::ParseFile, 0 errors)
- [x] template rule count = 40 (method: Get-ChildItem count)
- [x] loop semantics match install.sh: DISABLED-skip, diff-update, install-new (method: side-by-side code review)

* feat(install): SessionStart identity hook, post-compact reload directive, hook-merge dedup, horizon templates

## What
- session-start-identity.sh: new SessionStart hook injects a master-orchestrator
  identity anchor into context every session (reads rules/interactive-master-orchestrator.md
  if installed, else a generic anchor). Registered first in SessionStart in both installers.
- pre-compact-save.sh: now also prints a POST-COMPACT directive telling the next turn to
  run /load (restore state + re-read context) before continuing.
- Hook registration on re-install: per-event merge that preserves user-added hooks and
  dedups jitneuro's own. install.sh uses a jq filter; install.ps1 uses ConvertFrom-Json
  -AsHashtable on PS7 with a backup+replace fallback on Windows PowerShell 5.1.
- horizon/: 8 strategic-context placeholder templates + POPULATE-HORIZON.md interview guide;
  both installers seed them into <target>/horizon/ (only when empty).

## Why
Advisory-only identity in CLAUDE.md is not reliably honored; a mechanical SessionStart hook
guarantees it reaches context. Re-install previously clobbered user hooks. Adopters had no
guided way to capture their vision/mission/goals -- horizon templates + interview flow fix that.

## Risk
Installer + templates only. Verified end-to-end against throwaway targets:
- PS 5.1 fresh: 40 rules, 8 horizon, 12 hooks, valid settings.local.json, identity hook first
- PS 5.1 re-install: backup created, no dup hooks, valid JSON
- pwsh 7 re-install: user hook preserved, jitneuro hooks deduped, valid JSON
- bash fresh: 40 rules, 8 horizon, identity hook, valid settings.local.json
- All scripts parse clean (PS AST + bash -n); identity hook executes (exit 0)

## Test plan
- [x] PS 5.1 fresh + re-install to temp target (method: live powershell.exe -File run + JSON parse)
- [x] pwsh 7 smart-merge preserves user hook + dedups (method: live run with injected user hook)
- [x] bash fresh install to temp target (method: live bash run + python JSON validate)
- [x] hook line-endings normalize to LF via autocrlf; CRLF hook still executes (method: git show HEAD + live bash run)

* deploy: publish 175 validated artifacts from jit-knowledge

## What
Publishes the Owner-validated public knowledge set from jit-knowledge into
templates/<surface>/: 63 rules, 50 skills, 45 _patterns, 8 playbooks, 6 cognition,
2 references, 1 horizon. Adds templates/COMMUNITY-PUBLISH-MANIFEST.json (provenance:
source hash + override flag per artifact).

## Why
First population of the public framework with the canonical, sanitized knowledge set.
Generated by jit-knowledge/scripts/publish-to-jitneuro.py. Publish set =
scope:public AND validated(current hash) AND (leak-scan GREEN OR recorded override).
Authority is one-way jit-knowledge -> jitneuro.

## Risk
Content only (templates/). 26 pre-existing jitneuro-only template rules left untouched
(orphans; not pruned -- backport-not-delete). 1 artifact skipped (stale validation record,
source file renamed). No leak: every shipped file re-verified GREEN-or-override at export.

## Test plan
- [x] export dry-run selected 175, 0 problems, 1 expected skip (method: publish script dry-run)
- [x] all shipped files re-scanned GREEN-or-override at export time (method: scanner re-run in publish script)
- [x] provenance manifest written with 175 entries (method: JSON count)

* docs(install): document identity hook, horizon, post-compact recovery; degeneralize installer output

## What
- README + setup-guide: document the SessionStart master-orchestrator identity hook,
  the horizon strategic-context layer + POPULATE-HORIZON interview, the install-ready
  rule library, post-compact recovery, and the re-install hook-merge behavior (PS7 vs 5.1).
- Installer Next-steps: add the 'populate your horizon' step; replace the
  'add your jit-knowledge clone path' line (private-repo reference, meaningless to public
  adopters) with a generic 'map your repo names to local paths (optional)'.

## Why
Install behavior changed (identity hook, horizon templates, rule library, hook-merge dedup);
docs + on-screen install guidance now match what actually installs. Removes a confusing
private-repo reference from the public installer output.

## Risk
Docs + echo lines only. install.ps1 parses clean (AST); install.sh bash -n clean; PS 5.1
fresh install re-verified exit 0 (79 rules, 8 horizon, identity hook present).

* chore(public-prep): archive launch-prep, cut internal leaks, v0.5.0, multi-user gitignore

## What
- Archive 12 launch-ops/marketing root docs to gitignored zArchive/ (kept on disk, out of public HEAD).
- Cut notify-jit-knowledge.yml (live + template): internal jk-dispatch plumbing, failed red on forks, named an internal secret.
- Cut url-resolver.example.md (14 internal repos + personal paths); genericize url-resolver.md (the installed template) to generic placeholders.
- Genericize templates/_patterns/schema-evolution-defensive-parsing.md (removed jITSecure + a customer name).
- Sanitize .jitneuro/engrams/context.md: removed internal IP, company UUID, JITAI_OPENCLAW_PROD secret, CoWork/Paperclip section, PAT expiry; now a clean example engram at v0.5.0.
- Genericize one example host in templates/workspace.json (placeholder IP + repo name).
- Version coherence: v0.5.0 in jitneuro.json + CLAUDE.md + two docs.
- Expand templates/gitignore-additions.txt with personal-vs-shared (multi-user) block.

## Why
Make a fresh public clone clean for the demo: no internal infra/secrets/customer names in HEAD, coherent version, and a documented team gitignore so multi-user installs don't collide.

## Risk
Content + repo-hygiene only; installers' copy logic unchanged. zArchive/ preserved on disk (gitignored). jitneuro is already public, so these were already-public leaks; this cleans HEAD (history scrub is a separate decision).

## Test plan
- [x] high-severity leak grep on tracked tree = 0 (method: git grep for IP/secret/customer/personal-paths)
- [x] version strings = 0.5.0 in 4 files (method: grep)
- [x] zArchive gitignored + untracked, 12 files on disk (method: git check-ignore + ls)

* feat(install): upgrade-safe manifest -- separate framework files from user files

## What
Both installers now write .claude/.jitneuro-manifest.tsv (TSV: relpath + sha256, version
header) listing every FRAMEWORK-owned file. On re-install/upgrade:
- Prune framework files the new version dropped (sha-guarded; user-edited ones kept + flagged).
- Back up a framework rule the user edited before overwriting (.jitneuro-backup/rules/).
- Files NOT in the manifest = the user's own (their rules, bundles, engrams, horizon,
  owner-persona) -- NEVER touched.
Also fixes a pre-existing re-install bug: the broken  test ran
chmod 500 on hooks under Git Bash, so the next install's cp failed (Permission denied) and
aborted. Fixed with a proper  Windows-detection +  for hooks.

## Why
Owner concern: framework knowledge and user knowledge were intermixed in .claude/, making
every upgrade an entanglement risk (stale framework rules linger, user edits clobbered, no
ownership boundary). The manifest creates the boundary so a jitneuro upgrade is clean.
Chosen over reference-from-clone because Claude Code rule auto-loading from .claude/rules/
is the only confirmed mechanism (reference-from-clone depends on undocumented behavior).

## Risk
Installer-only. Manifest logic is dependency-free (sha256sum/shasum, Get-FileHash; TSV, no
jq/python). Mac-bash-3.2-safe (awk lookups, no assoc arrays). Manifest written ASCII (no BOM,
cross-tool safe). Verified end-to-end on throwaway targets.

## Test plan
- [x] bash fresh+upgrade (project): 129 tracked; user rule survived; framework edit backed up + reset; obsolete pruned; settings valid (method: live bash run to temp + asserts)
- [x] PS 5.1 fresh+upgrade (project): same asserts all pass (method: live powershell.exe run to temp, single invocation)
- [x] bash + PS user-mode fresh install (method: live run vs throwaway HOME/USERPROFILE)
- [x] pwsh7 hook smart-merge preserves user hooks + dedups (method: earlier live run)
- [x] re-install no longer aborts on chmod-locked hooks (method: 2x install to same temp, exit 0)

* docs(install): document upgrade-safe manifest model + single-user vs team

## What
- Setup guide: new "Upgrades Are Safe (Framework vs Your Files)" section explaining the
  manifest, the .jitneuro-backup behavior, and what the installer never touches.
- Setup guide: new "Single-User vs Team" section (per-dev user install; commit shared
  pieces; gitignore per-dev pieces via templates/gitignore-additions.txt).
- README: one "Upgrade-safe" bullet pointing to the Setup Guide.

## Why
The install behavior changed (manifest-tracked framework/user separation); docs now match.
Gives adopters a clear mental model: their files are theirs, framework files upgrade cleanly.

## Risk
Docs only.

## Test plan
- [x] sections render as valid markdown (method: read-back)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant