Skip to content

Self-healing journal import, .ctxrc promotion, GitNexus fold — reviewed & fixed#132

Merged
josealekhine merged 8 commits into
mainfrom
fix/jumbo-diff-review-fixes
Jul 7, 2026
Merged

Self-healing journal import, .ctxrc promotion, GitNexus fold — reviewed & fixed#132
josealekhine merged 8 commits into
mainfrom
fix/jumbo-diff-review-fixes

Conversation

@josealekhine

Copy link
Copy Markdown
Member

Summary

A multi-spec changeset (the "jumbo diff") put through a 4-pass adversarial code
review before merge. The review surfaced 20 findings (3 critical,
4 medium, 13 low); all are fixed, each with regression tests. Docs are
updated and the tracked docs site is rebuilt. Every commit carries a truthful
Spec: trailer and a DCO Signed-off-by.

267 files changed (including 182 generated site/ files; ~85 hand-edited
source/doc files).

What's in it (by spec)

feat: self-healing journal import (Phase JI)specs/journal-import-self-heal.md
ctx journal import becomes growth-aware: the unit of memory is the source
transcript (has it grown?), not the output file (does it exist?). --all
imports new sessions and completes any whose transcript has grown, skipping
only unchanged sources. Hand-edited entries are detected via a body render-hash
and never clobbered. Wired into a SessionEnd hook + the wrap-up ceremony, so it
self-heals with no flags to remember.

feat: promote runtime constants to .ctxrcspecs/ctxrc-constant-promotion.md
Six new opt-in .ctxrc keys: auto_prune_days, agent_cooldown_minutes,
task_budget_pct, convention_budget_pct, title_slug_max_len,
recall_list_limit. Absent keys preserve prior behavior.

chore: remove experimental spec-kit skills; add spec-driven recipespecs/remove-experimental-spec-kit-chain.md
Delete the unused ctx-experimental-{plan,spec,handoff} skills (they only
bridged to an unused spec-kit); add the operator-facing
spec-driven-development recipe and register it in the nav/index.

build: vendor GitNexus Docker tooling; drop npx gitnexusspecs/gitnexus-docker-fold.md
npx gitnexus doesn't run here (tree-sitter@0.21.1 vs Node 24). Vendor a Docker
wrapper (hack/gitnexus-*.sh) + Make targets. A registry_mounts helper guards
against GitNexus pruning registry entries whose paths it can't stat in-container
(fails loud on a missing python3 on registry-touching branches).

docs: repair site nav; fix connect→connection referencesspecs/docs-link-integrity.md
Add orphaned recipe/CLI pages to the nav; delete the stale cli/connect.md
(superseded by connection.md); fix broken ctx connect references. New
docs_nav_test.go guards nav reachability both ways (page↔nav).

chore: rebuild docs site + DCO governance
Regenerate the tracked site/ (zensical). Mandate DCO sign-off and forbid agent
sign-offs in CONSTITUTION.md, the session-start gate, and the /ctx-commit
skill (with Copilot mirror).

Adversarial review — 20 findings fixed

Critical

  • C1ctx journal site rewrote entry bodies in place without refreshing
    the render-hash, so growth-aware import false-flagged every site-normalized
    entry as foreign-edited and stranded it. Fixed: refresh the hash + persist
    state on every body-authoring pass.
  • C2 — a negative auto_prune_days moved the prune cutoff into the future
    and deleted every session-state file. Fixed: <= 0 guard in the getter
    and defensively in health.AutoPrune.
  • C3 — a negative title_slug_max_len reached a slice bound and panicked
    every ctx journal source/import. Fixed: <= 0 guard.

Medium

  • M1 — the source stat was committed at plan time, so a failed/partial grown
    write silently forgot the growth. Moved to execute, gated on a clean write.
  • M2agent_cooldown_minutes: 0 couldn't disable the cooldown. Cooldown
    and budget-percentage keys are now pointer types (explicit 0 ≠ unset).
  • M3 — resume/multi-file dedup kept first-seen by walk order, not the richest
    transcript. Now picks the largest; growth also compares the source path.
  • M4 — a v1→v2 adopted entry recorded no render-hash, mislabeling later
    growth as a foreign edit. Now backfills the hash at adoption.

LowGrownCount split (routine growth no longer trips the regenerate
prompt) · atomic entry writes · shell registry_mounts fail-open + python3
preflight · budget clamp to [0,1] and per-tier cap · nav-test sentinel +
reverse-link check · drift-proof reflection-based schema test · doc/wording
fixes.

New regression tests cover every confirmed bug: negative-value fallbacks,
0-disables-cooldown, budget clamp, adoption hash, failed-write-doesn't-strand,
GrownCount, and the full New → Unchanged → Grown → ForeignEdit self-heal
cycle.

Behavior / migration notes

  • Journal state schema v1 → v2 (per-session source tracking + per-entry
    render-hash). v1 files load tolerantly and round-trip as v2 on the next save.
  • ctx journal import --all no longer skips existing entries — it completes
    grown ones. Hand-edited entries are protected (detected by render-hash and
    left untouched with a warning).
  • The six new .ctxrc keys are opt-in; unset means prior defaults.

Testing

make build ✓ · gofmt clean · golangci-lint 0 issues · make test
0 failures (169 packages) · docs site rebuilt with zensical and verified
(new recipe rendered, stale connect page pruned).

Make `ctx journal import` growth-aware: the unit of memory becomes the
source transcript (has it grown?) rather than the output file (does it
exist?). --all now imports new sessions AND re-renders any whose
transcript has grown, skipping only unchanged sources; hand-edited
entries are detected via a body render-hash and never clobbered. Wired
into a SessionEnd hook and the wrap-up ceremony so it self-heals with no
flags to remember.

Adversarial-review fixes folded in:
- C1: `ctx journal site` refreshes the render-hash after its in-place
  body normalize (+ persists state); otherwise every site-normalized
  entry was false-flagged as a foreign edit and stranded.
- M1: the source stat is committed by execute only AFTER a clean write
  (via ImportPlan.Sources), so a failed/partial grown write no longer
  advances the stat and silently forgets the growth.
- M3: resume/multi-file dedup keeps the richest transcript (most
  messages) and growth compares the source path too, so switching to a
  larger resume copy counts as growth instead of truncating.
- M4: adopting a pre-v2 entry backfills its render-hash so a later
  growth sweep can self-heal it.
- L1: grown re-renders count as GrownCount, not RegenCount, so a routine
  interactive sweep no longer trips the regenerate prompt; the summary
  reports "complete N grown".
- L3: entry writes are atomic (temp+rename); the SessionEnd hook can be
  killed mid-write.
Regression tests: full New->Unchanged->Grown->ForeignEdit cycle plus a
failed-write-does-not-strand test.

Spec: specs/journal-import-self-heal.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Expose six previously-hardcoded knobs as .ctxrc keys: auto_prune_days,
agent_cooldown_minutes, task_budget_pct, convention_budget_pct,
title_slug_max_len, recall_list_limit. Absent keys keep prior behavior.

Adversarial-review fixes folded in:
- C2: auto_prune_days guards <=0 (getter + health.AutoPrune); a negative
  day count moved the prune cutoff into the future and deleted every
  session-state file.
- C3: title_slug_max_len guards <=0; a negative reached the slice bound
  in slug.FromTitle and panicked.
- M2: agent_cooldown_minutes/task_budget_pct/convention_budget_pct are
  pointer types, so an explicit 0 (disable / zero-allocation) is
  distinct from unset (default) rather than being coerced back.
- L5: budget percentages clamp to [0,1] and each tier caps at the
  remaining budget, so percentages summing past 1.0 can't overrun.
- L9: the schema-vs-struct bijection test reflects over the real
  rc.CtxRC (homed in package rc to avoid the assets->rc import cycle),
  so it can no longer drift from a hand-maintained copy.
- L10: slug/doc.go concurrency note corrected (FromTitle is not pure;
  Reset races the cache).
Regression tests: negative-value fallbacks, 0-disables-cooldown, budget
clamp, explicit-zero allocation.

Spec: specs/ctxrc-constant-promotion.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Delete the three EXPERIMENTAL (discardable) project skills
ctx-experimental-plan / -spec / -handoff. Their only reason to exist was
bridging ctx to spec-kit, which this project does not use (zero speckit
references outside the trio). ctx-experimental-plan duplicated /ctx-plan
and -spec was a lesser /ctx-spec; content is preserved in git history.

Add the operator-facing docs/recipes/spec-driven-development.md, the
full design->spec->implement pipeline narrative (/ctx-brainstorm,
/ctx-plan, /ctx-spec, /ctx-task-out, /ctx-implement), and register it in
the recipe index and design-before-coding cross-links. Review fix: the
"load-bearing rules" prose said four, the section lists five.

Spec: specs/remove-experimental-spec-kit-chain.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
npx gitnexus does not run on this box (tree-sitter@0.21.1 fails to build
against Node 24). Vendor a thin Docker wrapper that uses the official
arm64 image (Node 22 + prebuilt deps), staying off the host:
hack/gitnexus-docker.sh (index / mcp / passthrough), gitnexus-index.sh,
strip-gitnexus.sh, and make gitnexus-index / gitnexus-mcp /
strip-gitnexus targets. Replace every `npx gitnexus` reference in docs
and skills (GITNEXUS/CLAUDE/AGENTS, getting-started, multi-tool-setup,
ctx-remember, ctx-architecture-enrich).

Data-loss guard: GitNexus prunes registry entries whose paths it cannot
stat in-container, so the wrapper mounts every registered repo on all
registry-touching branches. Review fixes (shell): registry_mounts fails
loud (python3 preflight; hard-fail on non-empty-but-unparseable registry
on registration/passthrough branches) instead of fail-open; empty-array
expansions are set -u safe; strip-gitnexus preserves content on
unbalanced markers.

Spec: specs/gitnexus-docker-fold.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Add the batch of orphaned recipe and CLI pages to zensical.toml's nav
(KB recipes, dream, architecture-deep-dive, cli/kb|handover|dream|event|
message|bootstrap, runbooks) so they are reachable from the sidebar.
Delete the stale docs/cli/connect.md (superseded by connection.md) and
fix the leftover `ctx connect` references: the broken command in the
hub-deployment runbook becomes `ctx connection register`, and stale
`ctx connect` display labels across hub/CLI pages become `ctx
connection` (the command was renamed; no `connect` alias exists).

Guard: internal/compliance/docs_nav_test.go asserts every non-blog docs
page is in the nav AND every nav Markdown entry resolves to a real file
(so a deleted-but-still-linked page fails tests), with a sentinel that
prevents a vacuous pass. Also fixes a pre-existing broken doc icon
(lucide/message-square-cog -> message-square-text) that blocked any
site build.

Spec: specs/docs-link-integrity.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Regenerate the tracked site/ (zensical build + ctx site feed) so it
reflects the cumulative docs changes in this branch: the new
spec-driven-development recipe renders, the deleted connect page is
pruned, the repaired nav and the message-page icon fix land. site/ is
tracked with no CI build step, so it is staged with the docs it renders.

Persist the review outcome to .context: mark the adversarial-review task
done and record the session's learnings (site rewrites entry bodies ->
refresh render_hash; zensical's frozen lucide bundle; PATH ctx is a
stale install; assets<-rc import cycle).

Spec: specs/meta/chores.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Add a Process Invariant to CONSTITUTION.md (and a session-start reminder
to AGENT_PLAYBOOK_GATE.md): every commit must carry a DCO
`Signed-off-by:` trailer (commit with `git commit -s`) and must NOT
carry a `Co-Authored-By:` / agent-or-tool sign-off, overriding any
harness default that suggests one. Also require reading `git log -5` for
the trailer convention before the first commit of a session.

Prompted by six commits this session that carried an agent sign-off and
no DCO because the existing history's convention was never checked.
Both files are injected into every agent's context at session start, so
the rule reaches all agents rather than living only in one session's
private memory.

Spec: specs/spec-trailer-discipline.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
The ctx-commit skill said to include Signed-off-by but never said how
(git commit -s) and never forbade Co-Authored-By, so a bypass to raw
git commit produced commits with an agent sign-off and no DCO. Close
the gap: mandate `git commit -s`, explicitly prohibit `Co-Authored-By:`
/ agent-or-tool sign-offs, point at the CONSTITUTION Process Invariants,
and require checking `git log -5` for the trailer convention first.
Update the checklist and sync the Copilot-CLI mirror.

Spec: specs/spec-trailer-discipline.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
@josealekhine josealekhine self-assigned this Jul 7, 2026
@josealekhine josealekhine requested a review from bilersan as a code owner July 7, 2026 04:37
@josealekhine josealekhine merged commit f382bee into main Jul 7, 2026
17 checks passed
@josealekhine josealekhine deleted the fix/jumbo-diff-review-fixes branch July 7, 2026 04:41
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