Skip to content

Commit f4117b8

Browse files
committed
chore: namespace-cleanup docstring sweep + git push regex hardening
Combines two in-flight workstreams into one commit. ## Docstring namespace sweep (parallel agent) Follow-up to the CLI namespace cleanup in 78fbdf7. Updates doc comments, blog posts, recipes, and the regenerated site to reflect current command names (e.g. `ctx pause` → `ctx hook pause`, `ctx resume` → `ctx hook resume`, `ctx message` → `ctx hook message`). Also refreshes the Copilot CLI integration skills added in edaac81 (PR #63) to match the new namespace. Scope: ~450 files across docs/, site/, internal/cli, internal/write, internal/config, .github/, integration skill templates, and .claude/ skill SKILL.md files. ## Git push regex hardening (this session) The `block-dangerous-command` hook's `MidGitPush` regex only matched `git push` mid-command after `;`, `&&`, or `||`. This session accidentally bypassed it with `git -C <path> push` — the permissions deny list `Bash(git push *)` only matches prefix `git push`, so `git -C <path> push` also slipped through. Replace `MidGitPush` with a broader `GitPush` that covers: - Bare `git push` at command start - All separator and subshell entry points (`;`, `&&`, `||`, `|`, `&`, `(`, `$(`, backtick, newline) - Env-var and command-wrapper prefixes (`GIT_DIR=/x git push`, `time git push`, `nice git push`) - Any flag shape between `git` and `push` (`-C path`, `-c key=val`, `--git-dir=/path`, `--no-pager`, `--bare`, `-p`, `-P`) - Tail anchor that distinguishes subcommand from ref names (`push-to-remote`, `push_branch`) via `[^a-zA-Z0-9._/-]|$` Documented trade-offs: accepted false positives on `git log push` and `git commit -m push` (push as literal arg); known blind spots for `eval` / `sh -c` quoting and shell aliases. Adds `internal/config/regex/cmd_test.go` with 42 table-driven cases covering all entry points, flag shapes, prefixes, negative cases (other subcommands, ref-name continuations), and the accepted false-positive classes. Renames the Go symbol `MidGitPush` → `GitPush` to accurately reflect scope; keeps legacy variant string `mid-git-push` and text key `block.mid-git-push` (user-facing message is already generic: "git push requires explicit user approval"). Spec: specs/git-push-regex-hardening.md Spec: specs/cli-namespace-cleanup.md Signed-off-by: Jose Alekhinne <jose@parlakisik.com>
1 parent edaac81 commit f4117b8

493 files changed

Lines changed: 23827 additions & 16958 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/_ctx-backup/SKILL.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: _ctx-backup
33
description: "Backup project context and global Claude data to SMB share. Use before risky operations, at end of session, or on request."
4-
allowed-tools: Bash(ctx system backup*), Bash(ls /tmp/ctx-backup*)
4+
allowed-tools: Bash(ctx backup*), Bash(ls /tmp/ctx-backup*)
55
---
66

77
Backup `.context/`, `.claude/`, `ideas/`, and `~/.claude/` to
@@ -44,19 +44,19 @@ Based on the argument, run the appropriate command:
4444

4545
```bash
4646
# For "project"
47-
ctx system backup --scope project
47+
ctx backup --scope project
4848

4949
# For "global"
50-
ctx system backup --scope global
50+
ctx backup --scope global
5151

5252
# For "all" or no argument
53-
ctx system backup --scope all
53+
ctx backup --scope all
5454
```
5555

5656
## Process
5757

5858
1. Parse the argument (default to `all` if none provided)
59-
2. Run the appropriate `ctx system backup` command
59+
2. Run the appropriate `ctx backup` command
6060
3. Report the archive path and size from the output
6161
4. Confirm success to the user
6262

.context/CONVENTIONS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,9 @@ DO NOT UPDATE FOR:
256256
- Warn format strings centralized in config/warn/ — use warn.Close,
257257
warn.Write, warn.Remove, warn.Mkdir, warn.Rename, warn.Walk, warn.Getwd,
258258
warn.Readdir, warn.Marshal instead of inline format strings in log.Warn calls
259+
260+
- Nav frontmatter title: fields must not contain ctx — frontmatter does not support backticks, so the brand stays out of nav titles entirely (Hub, not The ctx Hub). Body headings can use `ctx` since markdown supports backticks.
261+
262+
- CLI flags and slash-commands inside headings or admonition titles must be backticked: `--keep-frontmatter=false`, `/ctx-reflect`. The title-case engine in hack/title-case-headings.py protects these patterns automatically, but authors should still backtick at write time for clarity.
263+
264+
- File extensions inside headings must be backticked when title-case capitalization would otherwise apply: write `CONSTITUTION.md`, not CONSTITUTION.Md. The title-case engine refuses to capitalize lowercase tokens following a literal . dot, but explicit backticks remain the clearest signal.

.context/DECISIONS.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
<!-- INDEX:START -->
44
| Date | Decision |
55
|----|--------|
6+
| 2026-04-14 | doc.go quality floor: behavior-grounded, ~25-100 body lines, related-packages section required |
7+
| 2026-04-14 | Bootstrap stays under ctx system bootstrap (reverted experimental top-level promotion) |
8+
| 2026-04-14 | Title Case style for docs is AP-leaning with explicit ambiguity carve-outs |
69
| 2026-04-13 | Walk boundary uses git as a hint, not a requirement |
710
| 2026-04-11 | Journal stays local; LEARNINGS.md is the shareable layer |
811
| 2026-04-11 | `Entry.Author` is server-authoritative, not client-authoritative |
@@ -122,6 +125,48 @@ For significant decisions:
122125
123126
-->
124127

128+
## [2026-04-14-010205] doc.go quality floor: behavior-grounded, ~25-100 body lines, related-packages section required
129+
130+
**Status**: Accepted
131+
132+
**Context**: About 140 doc.go files were rewritten this session. User flagged the original 5-line Key exports + See source files + Part of subsystem pattern as lazy minimum effort.
133+
134+
**Decision**: doc.go quality floor: behavior-grounded, ~25-100 body lines, related-packages section required
135+
136+
**Rationale**: Behavior-grounded rewrites (read source first, then write) are the only acceptable form for any non-trivial package. The lazy template communicates nothing a future reader cannot grep for; it satisfies tooling without adding signal.
137+
138+
**Consequence**: Every non-trivial package's doc.go now leads with the package's actual purpose, names key behaviors, calls out non-obvious design choices (Raft-lite, two-step indirection, idempotency contracts), and lists related packages with paths. New packages should follow the same shape.
139+
140+
---
141+
142+
## [2026-04-14-010205] Bootstrap stays under ctx system bootstrap (reverted experimental top-level promotion)
143+
144+
**Status**: Accepted
145+
146+
**Context**: Mid-session promoted ctx bootstrap to top-level to make a stale CLAUDE.md instruction work. User reverted it and reaffirmed the original design.
147+
148+
**Decision**: Bootstrap stays under ctx system bootstrap (reverted experimental top-level promotion)
149+
150+
**Rationale**: The ctx system namespace is for agent and hook plumbing the user does not type by hand. Bootstrap is invoked by AI agents at session start; surfacing it at top-level pollutes ctx --help for humans without benefit.
151+
152+
**Consequence**: internal/bootstrap/group.go reverted; internal/config/embed/cmd/system.go header now correctly states bootstrap is intentionally not promoted. The CLAUDE.md template across the repo (and the workspace copy) updated to reference ctx system bootstrap as canonical.
153+
154+
---
155+
156+
## [2026-04-14-010205] Title Case style for docs is AP-leaning with explicit ambiguity carve-outs
157+
158+
**Status**: Accepted
159+
160+
**Context**: Needed a deterministic Title Case engine for headings and admonition titles across docs/. User precedent (Working with AI lowercase with) ruled out strict Chicago.
161+
162+
**Decision**: Title Case style for docs is AP-leaning with explicit ambiguity carve-outs
163+
164+
**Rationale**: AP lowercase prepositions regardless of length matches user-approved titles. But strict AP would lowercase ambiguous prep/conj/adv words like before, after, since, until, past, near, down, up, off, hurting common cases. Carve-outs leave them at default-cap and let the engine reach a sensible result for ~95 percent of headings without manual review.
165+
166+
**Consequence**: hack/title-case-headings.py ships an AP-leaning with ambiguity carve-outs PREPOSITIONS set. Future style changes must touch that set explicitly with reasoning. New brand or acronym additions go through the same audited pattern.
167+
168+
---
169+
125170
## [2026-04-13-153617] Walk boundary uses git as a hint, not a requirement
126171

127172
**Status**: Accepted

.context/LEARNINGS.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ DO NOT UPDATE FOR:
1717
<!-- INDEX:START -->
1818
| Date | Learning |
1919
|----|--------|
20+
| 2026-04-14 | Constitution forbids context window as a deferral excuse |
21+
| 2026-04-14 | docs/cli/system.md and embed/cmd/system.go diverged on bootstrap promotion intent |
22+
| 2026-04-14 | Raft-lite trade-off is the load-bearing choice in internal/hub |
23+
| 2026-04-14 | AST stutter test only checks FuncDecl, not GenDecl |
24+
| 2026-04-14 | Brand-name handling in title-case engines must cover possessives |
2025
| 2026-04-13 | GPG signing from non-TTY contexts requires pinentry-mac (or equivalent) |
2126
| 2026-04-13 | Load average measures a queue, not CPU utilization |
2227
| 2026-04-13 | rc.ContextDir() is the single source of truth — fix the resolver, not callers |
@@ -115,6 +120,56 @@ DO NOT UPDATE FOR:
115120

116121
---
117122

123+
## [2026-04-14-010134] Constitution forbids context window as a deferral excuse
124+
125+
**Context**: Mid-session, agent proposed pacing through doc.go rewrites with the reasoning that context budget was tight.
126+
127+
**Lesson**: The CONSTITUTION explicitly lists 'We are running out of context window' as a forbidden deferral phrase under No Excuse Generation. The rule is real and applies to agent self-pacing, not just user-facing answers.
128+
129+
**Application**: When tempted to scope down because context is tight, re-read the constitution. The right move is to do the work end-to-end, not to ask the user which slice to skip.
130+
131+
---
132+
133+
## [2026-04-14-010134] docs/cli/system.md and embed/cmd/system.go diverged on bootstrap promotion intent
134+
135+
**Context**: Header comment in internal/config/embed/cmd/system.go claimed bootstrap was promoted to top-level; the bootstrap.go registration never actually promoted it. Two contradictory sources of truth coexisted silently.
136+
137+
**Lesson**: Header-comment claims about command-tree structure are unaudited; they can drift from registrations without any test failing. Trust the code, not the comment.
138+
139+
**Application**: When evaluating any package_name namespace cleanup type claim about command structure, verify against the actual cobra registration in internal/bootstrap/group.go before acting.
140+
141+
---
142+
143+
## [2026-04-14-010134] Raft-lite trade-off is the load-bearing choice in internal/hub
144+
145+
**Context**: Discovered while writing thorough doc.go for internal/hub. The package embeds HashiCorp Raft for leader election only; data replication is sequence-based gRPC sync over the append-only JSONL store.
146+
147+
**Lesson**: A leader crash window between accept and replicate can lose the most recent write. Append-only storage plus idempotent clients make this acceptable; full Raft log replication would not be needed and would not be simpler.
148+
149+
**Application**: Any future make hub stronger proposal must engage with this trade-off explicitly. Do not abandon Raft-lite accidentally by introducing log-replicated state; that would invalidate the simplicity argument.
150+
151+
---
152+
153+
## [2026-04-14-010134] AST stutter test only checks FuncDecl, not GenDecl
154+
155+
**Context**: tpl.TplEntryMarkdown stuttered for a long time because TestNoStutteryFunctions in internal/audit walks *ast.FuncDecl only; the constant slipped through.
156+
157+
**Lesson**: The audit suite has a real coverage gap for *ast.GenDecl (consts, vars, types). Stuttery type/const names will not be caught until the audit is extended to walk those node kinds.
158+
159+
**Application**: When a stuttery identifier is reported by a human, check both the offending file and whether the audit can catch it; if not, file an audit-extension task.
160+
161+
---
162+
163+
## [2026-04-14-010105] Brand-name handling in title-case engines must cover possessives
164+
165+
**Context**: First pass of hack/title-case-headings.py produced 'Ctx's' from 'ctx's' because the brand check matched the bare token only.
166+
167+
**Lesson**: A brand allowlist needs to recognize <brand>, <brand>'s, <brand>s, and short apostrophe-suffixed variants. Single-word matching misses contractions and possessives.
168+
169+
**Application**: When adding a new always-lowercase brand to hack/title-case-headings.py, extend the suffix-aware loop in title_case_word, not just the BRAND_LOWER set.
170+
171+
---
172+
118173
## [2026-04-13-153618] GPG signing from non-TTY contexts requires pinentry-mac (or equivalent)
119174

120175
**Context**: git commit failed from Claude Code's shell with 'gpg: signing

.context/TASKS.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,3 +2076,13 @@ disambiguates.
20762076
`make test` (0 failures including the audit exempt-list
20772077
update and the `gofmt` round-trip on `serve/cmd/root/cmd.go`).
20782078
#added:2026-04-11 #pr:60 #done:2026-04-11
2079+
2080+
### Later
2081+
2082+
- [ ] Optional follow-up doc.go pass: a handful of tiny per-subcommand wrappers under internal/cli/*/cmd/* still have ~5-line bodies. Most are accurate-but-brief; expand only if the brief form proves insufficient in review. #session:4b37e2f6 #branch:feat/copilot-cli-skill-parity-rebased #commit:edaac81786c9379333b352dae0d55df0ae0f72bb #added:2026-04-14-010311
2083+
2084+
- [ ] Extend internal/audit/stuttery_functions_test.go to cover *ast.GenDecl (consts, vars, types). Current implementation walks *ast.FuncDecl only and missed tpl.TplEntryMarkdown (since renamed to HubEntryMarkdown). #session:4b37e2f6 #branch:feat/copilot-cli-skill-parity-rebased #commit:edaac81786c9379333b352dae0d55df0ae0f72bb #added:2026-04-14-010311
2085+
2086+
- [ ] Decide whether to delete docs/cli/connect.md — verified dead duplicate of docs/cli/connection.md (uses old ctx connect command name; zero inbound references; not in zensical.toml). Awaiting explicit user OK before git rm. #session:4b37e2f6 #branch:feat/copilot-cli-skill-parity-rebased #commit:edaac81786c9379333b352dae0d55df0ae0f72bb #added:2026-04-14-010311
2087+
2088+
- [-] PROMPT.md design — belongs in another project; skipped here. #session:4b37e2f6 #added:2026-04-14-010311 #skipped:2026-04-14

.ctxrc.dev

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ key_rotation_days: 90 # Days before encryption key rotation nudge
5353

5454
# --- Webhook notifications ---
5555
# Notifications are opt-in: nothing fires unless events are listed.
56-
# Run `ctx notify setup` to configure the encrypted webhook URL first.
56+
# Run `ctx hook notify setup` to configure the encrypted webhook URL first.
5757
#
5858
notify:
5959
events:
@@ -73,5 +73,5 @@ notify:
7373
# qa-reminder — QA gate reminder emitted
7474
# block-non-path-ctx — blocked non-PATH ctx invocation
7575
#
76-
# Note: `ctx notify test` always bypasses the event filter — no need to
76+
# Note: `ctx hook notify test` always bypasses the event filter — no need to
7777
# list "test" here. It warns if filtered but sends anyway.

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ If `ctx` is installed, use these commands:
100100
ctx status # Context summary and health check
101101
ctx agent # AI-ready context packet
102102
ctx drift # Check for stale context
103-
ctx recall list # Recent session history
103+
ctx journal source --limit 5 # Recent session history
104104
```
105105

106106
<!-- ctx:copilot:end -->

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,14 @@ check-why:
306306
@diff -q docs/reference/design-invariants.md internal/assets/why/design-invariants.md || (echo "FAIL: design-invariants.md is stale — run 'make sync-why'" && exit 1)
307307
@echo "Why docs are in sync."
308308

309+
## title-case-check: Dry-run title-case checker on docs (or TARGET=path)
310+
title-case-check:
311+
@python3 hack/title-case-headings.py $${TARGET:-docs}
312+
313+
## title-case-fix: Apply title-case fixes to headings + admonition titles (TARGET=path defaults to docs)
314+
title-case-fix:
315+
@python3 hack/title-case-headings.py --apply $${TARGET:-docs}
316+
309317
## help: Show this help
310318
help:
311319
@echo "Context CLI - Available targets:"

docs/blog/2026-01-27-building-ctx-using-ctx.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ This is the story of `ctx`, how it evolved from a hasty "*YOLO mode*" experiment
3333
to a disciplined system for **persistent AI context**, and what I have
3434
learned along the way.
3535

36-
!!! info "Context is a Record"
36+
!!! info "Context Is a Record"
3737
**Context** *is a* **persistent record**.
3838

3939
By "*context*", I **don't** mean model memory or stored thoughts:
@@ -165,7 +165,7 @@ The `git` history tells the story:
165165
4f0e195 feat: separate orchestrator directive from agent tasks
166166
```
167167

168-
## YOLO Mode: Fast, But Dangerous
168+
## YOLO Mode: Fast, but Dangerous
169169

170170
The *Ralph Loop* made feature development *incredibly fast*.
171171

@@ -277,12 +277,12 @@ conventions...*) should go in to `CONVENTIONS.md`.
277277

278278
Here's how `ctx` explained why the distinction was important:
279279

280-
!!! tip "Decision record, 2026-01-25"
280+
!!! tip "Decision Record, 2026-01-25"
281281
Overly strict constitution creates friction and gets ignored.
282282

283283
Conventions can be bent; constitution **cannot**.
284284

285-
## Hooks: Harder Than They Look
285+
## Hooks: Harder than They Look
286286

287287
Claude Code hooks seemed simple: Run a script before/after certain events.
288288

@@ -339,7 +339,7 @@ By the time of this writing this project's `ctx` sessions
339339

340340
They are not part of the source code due to security, privacy, and size concerns.
341341

342-
!!! tip "Middle Ground: the Scratchpad"
342+
!!! tip "Middle Ground: The Scratchpad"
343343
For sensitive notes that *do* need to travel with the project,
344344
`ctx pad` stores encrypted one-liners in git, and
345345
`ctx pad add "label" --file PATH` can ingest small files.
@@ -470,7 +470,7 @@ The archive from January 23rd shows 13 phases of work:
470470

471471
That's an impressive ^^173 commits** across **8 days** of development.
472472

473-
## What I Learned About AI-Assisted Development
473+
## What I Learned about AI-Assisted Development
474474

475475
**1. Memory changes everything**
476476

@@ -551,7 +551,7 @@ If you are reading this, chances are that you already have heard about `ctx`.
551551
[github.com/ActiveMemory/ctx](https://github.com/ActiveMemory/ctx),
552552
* and the documentation lives at [ctx.ist](https://ctx.ist).
553553

554-
!!! note "Session Records are a Gold Mine"
554+
!!! note "Session Records Are a Gold Mine"
555555
By the time of this writing, I have **more than 70 megabytes** of
556556
**text-only** session capture, spread across >100 Markdown and `JSONL`
557557
files.

docs/blog/2026-02-01-ctx-v0.2.0-the-archaeology-release.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ topics:
2222

2323
![ctx](../images/ctx-banner.png)
2424

25-
## Digging Through the Past to Build the Future
25+
## Digging through the Past to Build the Future
2626

2727
*Jose Alekhinne / 2026-02-01*
2828

29-
!!! question "What if Your AI Could Remember Everything?"
29+
!!! question "What If Your AI Could Remember Everything?"
3030
Not just the current session, but **every** session:
3131

3232
* **Every** decision made,
@@ -74,7 +74,7 @@ I found myself grepping through files to answer questions like:
7474
* "*What was the session where we fixed the hook regex?*"
7575
* "*How did the `embed.go` split actually happen?*"
7676

77-
!!! note "Fate is Whimsical"
77+
!!! note "Fate Is Whimsical"
7878
The irony was **painful**:
7979

8080
I built a tool to prevent AI amnesia, but I was suffering from
@@ -114,7 +114,7 @@ them in a human-readable format:
114114
Slugs are auto-generated from session IDs (*memorable names instead of
115115
UUIDs*). The goal (*as the name implies*) is **recall**, not archival accuracy.
116116

117-
!!! note "2,121 lines of new code"
117+
!!! note "2,121 Lines of New Code"
118118
The `ctx recall` feature was the largest single addition:
119119

120120
parser library, CLI commands, test suite, and slash command.
@@ -214,7 +214,7 @@ ctx add learning "CGO breaks ARM64 builds" \
214214
--application "Added to Makefile and CI config"
215215
```
216216

217-
!!! quote "Structured entries are prompts to the AI"
217+
!!! quote "Structured Entries Are Prompts to the AI"
218218
When the AI reads a decision with full context, rationale, and
219219
consequences, it understands the **why**, *not* just the **what**.
220220

@@ -250,7 +250,7 @@ always loaded first.
250250

251251
The same structure serves two very different readers.
252252

253-
!!! tip "Reindex after manual edits"
253+
!!! tip "Reindex After Manual Edits"
254254
If you edit entries by hand, rebuild the index with:
255255

256256
```bash
@@ -301,7 +301,7 @@ a human can **reason** about.
301301

302302
### 2. Enforcement > Documentation
303303

304-
!!! quote "The Prompt is a Guideline"
304+
!!! quote "The Prompt Is a Guideline"
305305
The code is more what you'd call '*guidelines*' than actual rules.
306306

307307
-**Hector Barbossa**
@@ -324,7 +324,7 @@ The journal system started as a way to understand `ctx` itself.
324324

325325
It immediately became useful for everything else.
326326

327-
## v0.2.0 in The Numbers
327+
## v0.2.0 in the Numbers
328328

329329
This was a heavy release. The numbers reflect that:
330330

0 commit comments

Comments
 (0)