@gi4nks/ph 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,14 @@
10
10
  { "id": "gemini-import", "project": "ph", "text": "Gemini history import reads session JSON, pairs human messages with the following model response, and supports dry run and duplicate filtering." },
11
11
  { "id": "remote-sync", "project": "ph", "text": "Remote sync pushes unsynced prompts and pulls newer records; sync hashes deduplicate matching prompt, response, tool, and arguments." },
12
12
  { "id": "analysis-memory", "project": "ph", "text": "Background analysis appends project memories and merges key insights and technical decisions into a single project summary." },
13
+ { "id": "shared-context", "project": "ph", "text": "getProjectContext and formatProjectContext are shared by ph context, chat, and MCP; semantic retrieval must stay project scoped." },
14
+ { "id": "wise-provider", "project": "ph", "text": "Wise provides OpenRouter and MLX-Serve providers in ph; provider and model configuration is shared across CLI and TUI." },
15
+ { "id": "homo-provider-boundary", "project": "homo", "text": "HOMO uses the shared Wise library to configure multiple AI providers behind the application's AI integration." },
16
+ { "id": "homo-genesis-context", "project": "homo", "text": "Chapter Genesis carries previous content fragments and book-level lore constraints into generated scenes." },
17
+ { "id": "picot-sqlite-build", "project": "picot", "text": "PicoT uses SQLite and Next.js; builds should use a SQLite timeout and isolated build data to avoid SQLITE_BUSY races." },
18
+ { "id": "picot-breadcrumb-context", "project": "picot", "text": "PicoT document preview preserves the originating library listing, search, and filters through breadcrumb navigation." },
19
+ { "id": "lens-harness-goal", "project": "lens", "text": "Lens integrates the harness goal loop with verified predicates, progress, recovery, and a run_command tool." },
20
+ { "id": "lens-wise-provider", "project": "lens", "text": "Lens WiseProvider supports OpenRouter and MLX-Serve using configured provider model IDs." },
13
21
  { "id": "unrelated-react", "project": "lens", "text": "React rendering uses reconciliation to compare virtual trees and update the browser DOM." },
14
22
  { "id": "unrelated-go", "project": "sonic", "text": "Go goroutines communicate using channels and are scheduled by the Go runtime." }
15
23
  ],
@@ -21,6 +29,14 @@
21
29
  { "query": "How are assistant replies and hidden reasoning handled in Claude imports?", "relevant": ["claude-import"] },
22
30
  { "query": "How does Gemini history import pair prompt and model output?", "relevant": ["gemini-import"] },
23
31
  { "query": "How does ph avoid duplicate records when synchronizing laptops?", "relevant": ["remote-sync"] },
24
- { "query": "How do prompt analyses update the long term project knowledge?", "relevant": ["analysis-memory"] }
32
+ { "query": "How do prompt analyses update the long term project knowledge?", "relevant": ["analysis-memory"] },
33
+ { "query": "Which shared retrieval API do CLI, chat, and MCP use?", "relevant": ["shared-context"] },
34
+ { "query": "How are Wise models and providers configured in ph?", "relevant": ["wise-provider"] },
35
+ { "query": "How does HOMO pass earlier chapter context and lore into generation?", "relevant": ["homo-genesis-context"] },
36
+ { "query": "Which provider abstraction does HOMO use for AI backends?", "relevant": ["homo-provider-boundary"] },
37
+ { "query": "How should PicoT builds avoid SQLite locking conflicts?", "relevant": ["picot-sqlite-build"] },
38
+ { "query": "What state does PicoT preserve when navigating back from a document?", "relevant": ["picot-breadcrumb-context"] },
39
+ { "query": "How does Lens verify and recover an agent goal?", "relevant": ["lens-harness-goal"] },
40
+ { "query": "Which local and hosted AI providers are available to Lens?", "relevant": ["lens-wise-provider"] }
25
41
  ]
26
42
  }
@@ -0,0 +1,179 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>PH Architecture Review</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
9
+ <style>
10
+ :root { color-scheme: light; --ink:#17212b; --muted:#52616d; --line:#d9e1e5; --paper:#f5f7f6; --teal:#087f74; --amber:#a85c05; --rose:#bd3e4b; }
11
+ body { background:var(--paper); color:var(--ink); font-family:Inter,ui-sans-serif,system-ui,-apple-system,sans-serif; }
12
+ h1,h2,h3,h4,.serif { font-family:Georgia,Cambria,"Times New Roman",serif; }
13
+ .module-box { border:1px solid #a8b8bf; border-radius:1rem; padding:1rem; background:#fff; box-shadow:0 10px 30px #162a3010; }
14
+ .diagram-arrow { color:#73848c; font-size:1.35rem; line-height:1; }
15
+ .seam-line { border-top:2px dashed var(--teal); position:relative; }
16
+ .seam-line:after { content:"SEAM"; position:absolute; right:0; top:-.78rem; padding:0 .45rem; background:white; color:var(--teal); font-size:.65rem; font-weight:800; letter-spacing:.12em; }
17
+ .mermaid { overflow-x:auto; background:#fff; padding:1.25rem; border:1px solid var(--line); border-radius:1rem; }
18
+ .evidence { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.8rem; overflow-wrap:anywhere; }
19
+ .impact td,.impact th { padding:.55rem .65rem; border-bottom:1px solid var(--line); text-align:left; vertical-align:top; }
20
+ @media print { body { background:white; } .module-box,.mermaid { box-shadow:none; break-inside:avoid; } }
21
+ </style>
22
+ </head>
23
+ <body>
24
+ <main class="max-w-6xl mx-auto px-5 sm:px-8 py-10 sm:py-16">
25
+ <header class="border-b border-slate-300 pb-10">
26
+ <div class="flex flex-wrap gap-3 items-center text-sm text-slate-600">
27
+ <span class="rounded-full bg-slate-200 px-3 py-1 font-semibold">PH · PROMPT HISTORY</span>
28
+ <span>Architecture review</span><span>22 October 2026</span>
29
+ <span class="rounded-full bg-amber-100 text-amber-900 px-3 py-1 font-semibold">Working tree dirty</span>
30
+ </div>
31
+ <h1 class="serif text-5xl sm:text-6xl mt-8 leading-tight">A useful core under too many surfaces</h1>
32
+ <p class="mt-7 text-xl sm:text-2xl font-bold max-w-4xl">Strength: local capture, SQLite storage, and project-scoped retrieval form a coherent foundation with useful seams.</p>
33
+ <p class="mt-3 text-xl sm:text-2xl font-bold text-rose-800 max-w-4xl">Flaw: PH keeps adding command, transport, and knowledge workflows faster than it proves which ones users need.</p>
34
+ <div class="flex flex-wrap gap-3 mt-8 text-sm">
35
+ <span class="rounded-lg bg-slate-800 text-white px-3 py-2">Module</span>
36
+ <span class="rounded-lg border-2 border-dashed border-teal-700 text-teal-900 px-3 py-2">Seam</span>
37
+ <span class="rounded-lg border-2 border-dashed border-rose-600 text-rose-800 px-3 py-2">Leakage / unwired</span>
38
+ <span class="rounded-lg bg-teal-800 text-white px-3 py-2">Deep Module</span>
39
+ </div>
40
+ <p class="mt-6 max-w-4xl text-slate-600">This review describes the current working tree, including uncommitted operational-memory changes. It does not treat documentation or a passing test suite as proof of adoption.</p>
41
+ </header>
42
+
43
+ <section class="py-12 border-b border-slate-300">
44
+ <h2 class="serif text-3xl">Current Posture</h2>
45
+ <p class="mt-4 max-w-4xl text-slate-700">PH has a strong local-first data path and a meaningful retrieval boundary. Prompt capture remains useful without an LLM; semantic retrieval is optional; user approval gates curated memory writes. In this pass the MCP composition root was reduced to protocol setup, while memory and archive SQL moved behind repositories. The remaining concern is scope: a broad command set still exceeds what the operational workflow has validated.</p>
46
+ <div class="grid md:grid-cols-3 gap-4 mt-7">
47
+ <div class="module-box"><div class="text-3xl font-bold">97</div><div class="text-sm text-slate-600 mt-1">TypeScript / TSX source files</div></div>
48
+ <div class="module-box"><div class="text-3xl font-bold">17</div><div class="text-sm text-slate-600 mt-1">Test files; 94 tests passed in this checkout</div></div>
49
+ <div class="module-box"><div class="text-3xl font-bold">482 · 50 · 521 · 964</div><div class="text-sm text-slate-600 mt-1">Lines in CLI, MCP composition root, PhDB facade, and BrowseApp respectively</div></div>
50
+ </div>
51
+ <div class="mt-6 grid md:grid-cols-2 gap-5 text-sm">
52
+ <div class="rounded-xl border border-slate-300 bg-white p-5"><h3 class="font-bold text-teal-900">Rules the system respects</h3><ul class="list-disc pl-5 mt-3 space-y-1 text-slate-700"><li>SQLite is the source of truth; Ollama and generative providers are optional.</li><li>Project filters are applied inside semantic retrieval before limiting results.</li><li>Operational `prepare` is read-only; `close` asks for approval before promotion.</li><li>CLI and MCP share task-context retrieval and atomic memory promotion use cases.</li><li>Memory and archive repositories share the existing SQLite connection through the stable PhDB facade.</li></ul></div>
53
+ <div class="rounded-xl border border-rose-200 bg-rose-50 p-5"><h3 class="font-bold text-rose-900">Rules that are not yet proven</h3><ul class="list-disc pl-5 mt-3 space-y-1 text-slate-700"><li>The plan's three real tasks across different projects are not evidenced; it records one temporary-database usage check.</li><li>MCP-only tools still own some search and rendering decisions inside their grouped handler modules.</li><li>Feature breadth spans history capture, analysis, memory, TUI, MCP, import, archive, and remote sync.</li><li>Embedding-backed retrieval quality has not been evaluated in this pass.</li></ul></div>
54
+ </div>
55
+ <p class="mt-5 text-sm text-slate-600">Verification observed: <span class="font-semibold">npm test</span> passed (17 files, 94 tests), <span class="font-semibold">npm run lint</span>, <span class="font-semibold">npm run build</span>, and `npx tsc --noEmit` all passed. A separate embedding-backed retrieval evaluation was not run.</p>
56
+ </section>
57
+
58
+ <section class="py-12 border-b border-slate-300">
59
+ <h2 class="serif text-3xl">Runtime Map</h2>
60
+ <p class="mt-3 max-w-4xl text-slate-700">Solid teal marks high-leverage modules; dashed red marks broad adapters or duplicated routes where responsibilities leak across boundaries.</p>
61
+ <div class="mermaid mt-6">
62
+ flowchart LR
63
+ User[User / agent] --> CLI[CLI dispatch and commands]
64
+ Hooks[CLI hooks and importers] --> Capture[Capture normalization]
65
+ CLI --> Capture
66
+ Capture --> DB[(SQLite / PhDB)]
67
+ CLI --> Retrieval[Project context retrieval]
68
+ MCP[MCP protocol composition] --> MCPTools[Grouped prompt, project, timeline handlers]
69
+ MCPTools --> Retrieval
70
+ Retrieval --> DB
71
+ Retrieval --> Embed[Embedding endpoint]
72
+ Retrieval --> Render[Shared context formatter]
73
+ Render --> CLI
74
+ Render --> MCPTools
75
+ CLI --> Close[Close proposal and approval]
76
+ Close --> Provider[Analysis provider]
77
+ Close --> DB
78
+ MCPTools --> DB
79
+ DB --> Vec[Semantic index]
80
+ CLI --> TUI[Ink browser]
81
+ TUI --> DB
82
+ CLI --> Remote[HTTP sync client]
83
+ Remote --> Server[HTTP sync server]
84
+ Server --> DB
85
+ classDef deep fill:#075e57,stroke:#064e48,color:#fff,stroke-width:2px;
86
+ classDef module fill:#e6f4f1,stroke:#0c8276,color:#153b38,stroke-width:1.5px;
87
+ classDef leak fill:#fff0f1,stroke:#c2414c,color:#762631,stroke-width:2px,stroke-dasharray:6 4;
88
+ classDef external fill:#f1f5f9,stroke:#64748b,color:#1e293b;
89
+ class Capture,Retrieval,Render,Vec deep;
90
+ class CLI,Close,TUI,DB,MCP,MCPTools module;
91
+ class Remote,Server leak;
92
+ class User,Hooks,Embed,Provider external;
93
+ </div>
94
+ <div class="grid md:grid-cols-3 gap-4 mt-5 text-sm">
95
+ <div class="module-box"><b>Capture Seam</b><p class="mt-2 text-slate-600">`src/capture/index.ts` normalizes direct logging, wrappers, and importers before persistence.</p></div>
96
+ <div class="module-box"><b>Retrieval Seam</b><p class="mt-2 text-slate-600">`src/knowledge/task-context.ts` shares bounded task retrieval across prepare and MCP; `src/context/index.ts` serves context and chat formatting.</p></div>
97
+ <div class="module-box border-rose-300"><b>Persistence Leakage</b><p class="mt-2 text-slate-600">The stable `PhDB` facade still exposes a broad prompt API; repository interfaces remain internal and SQLite-specific.</p></div>
98
+ </div>
99
+ </section>
100
+
101
+ <section class="py-12 border-b border-slate-300">
102
+ <h2 class="serif text-3xl">Candidates / Opportunities for Deepening</h2>
103
+ <p class="mt-3 text-slate-700 max-w-4xl">These are targeted reductions in real Leakage. They are not a proposal to replace the stack or split every file.</p>
104
+
105
+ <article class="mt-8 rounded-2xl border border-rose-200 bg-white p-6 sm:p-8">
106
+ <div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">1. Contain product scope until real-use evidence exists</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented as a scope gate</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P0</span></div></div>
107
+ <p class="evidence mt-4 text-slate-600">Evidence: `src/cli.ts:46-155` advertises a wide command set; `src/commands/` has 26 handlers; `README.md` describes capture, imports, analysis, memories, TUI, MCP, archive, and remote sync; `ROADMAP.md` now gates new user-facing work on three real tasks across projects.</p>
108
+ <h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">PH now has several overlapping ways to retrieve project knowledge (`context`, `prepare`, chat injection, MCP knowledge checks) plus a separate curation flow. The tool's command count is growing while the core promise—capture useful history and find it again—has no adoption or success measure in the repo. This is product-scope Leakage: every surface needs help, docs, compatibility, and tests.</p>
109
+ <h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">Keep the current commands available, state their distinct jobs, and defer new commands, transports, or knowledge workflows until the `prepare → work → close → promote` loop is used on three real tasks in different projects. The gate is now recorded in `ROADMAP.md`; no existing capability was removed.</p>
110
+ <div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before · surface area</b><div class="mt-3 flex flex-wrap gap-2 text-xs"><span class="bg-rose-50 p-2 rounded">context</span><span class="bg-rose-50 p-2 rounded">prepare</span><span class="bg-rose-50 p-2 rounded">chat context</span><span class="bg-rose-50 p-2 rounded">MCP check</span><span class="bg-rose-50 p-2 rounded">close</span><span class="bg-rose-50 p-2 rounded">save decision</span></div></div><div class="module-box border-teal-700"><b>After · gated growth</b><div class="mt-3 flex items-center gap-2 text-xs"><span class="bg-teal-50 p-2 rounded">capture</span><span class="diagram-arrow">→</span><span class="bg-teal-50 p-2 rounded">retrieve evidence</span><span class="diagram-arrow">→</span><span class="bg-teal-50 p-2 rounded">curate if useful</span></div><p class="mt-2 text-xs text-teal-900">No new surface until real-use gate.</p></div></div>
111
+ <div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> a user-visible workflow contract that works through CLI and MCP without duplicating domain decisions. <b>Deep Module:</b> the smallest evidence-backed workflow PH can make dependable.</p>
112
+ <table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>Less maintenance per feature and clearer product promise.</td><td>Related user actions converge on fewer entry points.</td><td>Add outcome checks for retrieval usefulness and accepted promotions, not just command behavior.</td></tr></table>
113
+ </article>
114
+
115
+ <article class="mt-6 rounded-2xl border border-amber-200 bg-white p-6 sm:p-8">
116
+ <div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">2. Give knowledge promotion one atomic persistence operation</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P1</span></div></div>
117
+ <p class="evidence mt-4 text-slate-600">Evidence: the previous implementation issued two writes per proposal. `PhDB.promoteMemories()` now delegates to the memory repository (`src/db/index.ts:473`); the shared provenance and promotion use case is `src/knowledge/promotion.ts`, used by CLI (`src/commands/close.ts:101`) and MCP (`src/mcp/tools/projects.ts:8,21`). A rollback test covers the transaction in `src/db/__tests__/phdb.test.ts`.</p>
118
+ <h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">Before this review, staged approval did not guarantee atomic persistence. A failed summary update or later proposal could leave a partial result. The fix now places the approved batch in one SQLite transaction; this candidate is addressed in the current working tree.</p>
119
+ <h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">The shared promotion operation accepts the approved proposal batch and writes memories plus aggregate summaries atomically. CLI and MCP use the same operation. Provider generation and interactive review stay outside the transaction; the Seam is the approved proposal batch.</p>
120
+ <div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before</b><div class="mt-3 flex items-center gap-2 text-xs"><span>insert memory</span><span class="diagram-arrow">→</span><span>update summary</span><span class="diagram-arrow">→</span><span>repeat</span></div><p class="mt-2 text-xs text-rose-800">Failure can leave partial state.</p></div><div class="module-box border-teal-700"><b>After</b><div class="mt-3 rounded-lg bg-teal-50 p-3 text-xs">Approved batch <span class="diagram-arrow">→</span> single DB transaction <span class="diagram-arrow">→</span> consistent memories + summaries</div></div></div>
121
+ <div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> transport-independent promotion input. <b>Deep Module:</b> persistence owns consistency and exposes one operation with a simple result.</p>
122
+ <table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>Both CLI and MCP get the same all-or-nothing guarantee.</td><td>Memory and summary consistency live beside database writes.</td><td>Inject a failure midway and assert neither side changed.</td></tr></table>
123
+ </article>
124
+
125
+ <article class="mt-6 rounded-2xl border border-amber-200 bg-white p-6 sm:p-8">
126
+ <div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">3. Thin the MCP composition root and share cross-transport work</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented; handlers remain adapters</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P1</span></div></div>
127
+ <p class="evidence mt-4 text-slate-600">Evidence: `src/mcp/server.ts` is now 50 lines. Tool definitions live in `src/mcp/tools/definitions.ts`; prompt, project, and timeline handlers are grouped in `src/mcp/tools/`; formatting is isolated in `format.ts`. `src/knowledge/{task-context,promotion}.ts` centralize shared retrieval and persistence.</p>
128
+ <h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">The original server mixed protocol registration, all handlers, retrieval policy, writes, and formatting. The composition root is now small and tool code is local by domain. Some MCP-only search, timeline, and output behavior remains in adapter modules, so the transport boundary is improved but not fully domain-neutral.</p>
129
+ <h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">The composition root now owns MCP SDK registration, handler dispatch, and error envelopes. Shared task-context retrieval and memory promotion live under `src/knowledge/` and are called by CLI and MCP. Tool-specific protocols and renderers remain grouped under `src/mcp/tools/`; further extraction should wait for another consumer.</p>
130
+ <div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before</b><div class="mt-3 text-xs space-y-2"><div class="rounded bg-rose-50 p-2">MCP root owns tool declarations, queries, fallback, and formatting</div><div class="rounded bg-rose-50 p-2">MCP root validates sources and performs persistence</div></div></div><div class="module-box border-teal-700"><b>After</b><div class="mt-3 text-xs space-y-2"><div class="rounded bg-teal-50 p-2">MCP root → grouped tool handlers → shared task-context use case</div><div class="rounded bg-teal-50 p-2">CLI / MCP → shared promotion use case → PhDB facade</div></div></div></div>
131
+ <div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> transport-neutral application operations. <b>Deep Module:</b> reusable project knowledge behavior with a compact input/output contract.</p>
132
+ <table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>New transports reuse product behavior instead of cloning it.</td><td>Protocol concerns stop interleaving with retrieval and writes.</td><td>Use-case tests avoid MCP protocol setup; adapter tests focus on schemas and errors.</td></tr></table>
133
+ </article>
134
+
135
+ <article class="mt-6 rounded-2xl border border-amber-200 bg-white p-6 sm:p-8">
136
+ <div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">4. Split cohesive persistence behind the PhDB facade</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented for memory and archive</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P2</span></div></div>
137
+ <p class="evidence mt-4 text-slate-600">Evidence: `src/db/index.ts` is now a 521-line public facade with prompt CRUD, FTS, migrations, and query forwarding. Memory and summary persistence moved to `src/db/memory-repository.ts`; archive persistence moved to `src/db/archive-repository.ts`; vectors remain in `src/db/semantic-index.ts`.</p>
138
+ <h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">PhDB previously owned SQL for prompt CRUD, FTS, archives, memories, and summaries in one implementation. Memory and archive SQL now live in cohesive repositories over the same connection. The facade deliberately retains source compatibility; prompt CRUD and FTS remain one group.</p>
139
+ <h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">The extraction keeps prompt CRUD/FTS in the facade and moves memory/summary and archive SQL behind internal repositories. All repositories share one SQLite connection; `PhDB` method names and return values stay stable. Avoid widening the repository abstraction until a second adapter needs it.</p>
140
+ <div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before</b><div class="mt-3 flex flex-wrap gap-2 text-xs"><span class="bg-rose-50 rounded p-2">PhDB: prompt</span><span class="bg-rose-50 rounded p-2">memory</span><span class="bg-rose-50 rounded p-2">summary</span><span class="bg-rose-50 rounded p-2">archive</span><span class="bg-rose-50 rounded p-2">migrations</span></div></div><div class="module-box border-teal-700"><b>After</b><div class="mt-3 flex items-center gap-2 text-xs"><span class="bg-teal-50 rounded p-2">PhDB prompt facade</span><span class="diagram-arrow">→</span><span class="border-2 border-dashed border-teal-700 rounded p-2">MemoryRepository<br>ArchiveRepository</span><span class="diagram-arrow">→</span><span class="bg-teal-50 rounded p-2">shared SQLite</span></div></div></div>
141
+ <div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> existing PhDB-to-SQLite boundary, narrowed around use cases. <b>Deep Module:</b> a repository operation that hides SQL and guarantees its domain invariant.</p>
142
+ <table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>Changes to archive or memory behavior affect fewer consumers.</td><td>Each persistence concern owns its schema/query details.</td><td>Test repository invariants against temporary SQLite; use-case tests use a small contract.</td></tr></table>
143
+ </article>
144
+ </section>
145
+
146
+ <section class="py-12 border-b border-slate-300">
147
+ <h2 class="serif text-3xl">Top Recommendation</h2>
148
+ <div class="mt-5 rounded-2xl bg-slate-900 text-white p-6 sm:p-8">
149
+ <p class="text-teal-200 text-sm uppercase tracking-widest font-bold">First move · validate the operational workflow</p>
150
+ <h3 class="serif text-3xl mt-3">Do not add another memory feature yet</h3>
151
+ <p class="mt-4 max-w-4xl text-slate-200">Three structural actions are now in place: a product-scope gate, transport-neutral task-context and promotion operations with grouped MCP modules, and internal memory/archive repositories behind the unchanged PhDB API. Keep `prepare` as a read-only experiment. The remaining product test is three real tasks on different projects; record whether the brief prevented repeated work before adding more features.</p>
152
+ <p class="mt-4 max-w-4xl text-slate-200">Why this comes first: the biggest risk is not that PH lacks another abstraction. It is that summaries, memories, and tool-specific retrieval behavior drift while product value remains unmeasured. A transaction seam protects data now; a usage gate protects the project from building maintenance around an unproven loop.</p>
153
+ </div>
154
+ </section>
155
+
156
+ <section class="py-12 border-b border-slate-300">
157
+ <h2 class="serif text-3xl">Usage Modes</h2>
158
+ <div class="grid md:grid-cols-2 gap-4 mt-6">
159
+ <div class="module-box"><h3 class="font-bold">Capture and import history</h3><p class="mt-2 text-sm text-slate-600">Direct logging, wrappers, hooks, and importers normalize into prompt records.</p><p class="evidence mt-3">`src/capture/index.ts`, `src/importer/`, `src/commands/log.ts`, `hooks/`</p></div>
160
+ <div class="module-box"><h3 class="font-bold">Search local prompt history</h3><p class="mt-2 text-sm text-slate-600">SQLite FTS supports text search; sqlite-vec adds optional semantic search.</p><p class="evidence mt-3">`src/commands/search.ts`, `src/db/index.ts:246-345`, `src/db/semantic-index.ts`</p></div>
161
+ <div class="module-box"><h3 class="font-bold">Browse and curate records</h3><p class="mt-2 text-sm text-slate-600">The Ink interface filters, previews, edits metadata, exports, and reruns prompts.</p><p class="evidence mt-3">`src/ui/BrowseApp.tsx`, `src/ui/FilterPanel.tsx`, `src/ui/PreviewPane.tsx`</p></div>
162
+ <div class="module-box"><h3 class="font-bold">Expose history and project context to agents</h3><p class="mt-2 text-sm text-slate-600">MCP serves prompt queries and project knowledge; project tools call shared task-context retrieval and promotion use cases.</p><p class="evidence mt-3">`src/mcp/server.ts`, `src/mcp/tools/`, `src/knowledge/`</p></div>
163
+ <div class="module-box"><h3 class="font-bold">Prepare and promote operational knowledge</h3><p class="mt-2 text-sm text-slate-600">`prepare` retrieves a bounded brief; `close` proposes curated memory after provider analysis and user approval. Implemented in the current dirty tree; three-project real-use validation remains outstanding.</p><p class="evidence mt-3">`src/commands/prepare.ts`, `src/commands/close.ts`, `docs/specs/SPEC-016-operational-memory.md`</p></div>
164
+ <div class="module-box"><h3 class="font-bold">Synchronize with a remote PH server</h3><p class="mt-2 text-sm text-slate-600">An optional HTTP service supports prompt push/pull and memory lookups. It adds a second deployment and security surface.</p><p class="evidence mt-3">`src/server/index.ts`, `src/commands/remote.ts`</p></div>
165
+ </div>
166
+ <div class="mt-8 grid md:grid-cols-2 gap-4">
167
+ <div class="rounded-xl bg-teal-50 border border-teal-300 p-5"><h3 class="font-bold text-teal-950">Ready for...</h3><p class="mt-2 text-sm text-slate-700">Local prompt capture, search, browsing, and opt-in agent access to a user's own project history. The operational-memory commands are implemented and pass their current automated suite.</p></div>
168
+ <div class="rounded-xl bg-rose-50 border border-rose-300 p-5"><h3 class="font-bold text-rose-950">Still requires integration...</h3><p class="mt-2 text-sm text-slate-700">Evidence that the prepare/close loop improves real tasks; retrieval evaluation against the configured embedding model; and a coherent support boundary for the many transports and commands.</p></div>
169
+ </div>
170
+ </section>
171
+
172
+ <footer class="pt-8 text-sm text-slate-600 flex flex-wrap justify-between gap-3">
173
+ <span>PH Architecture Review · Based on the working tree at review time</span>
174
+ <span>Created: 2026-10-22 · Updated: 2026-10-22</span>
175
+ </footer>
176
+ </main>
177
+ <script>mermaid.initialize({startOnLoad:true,theme:'neutral',securityLevel:'strict'});</script>
178
+ </body>
179
+ </html>
package/docs/ph-manual.md CHANGED
@@ -1,16 +1,14 @@
1
1
  # ph — Prompt History and Project Memory
2
2
 
3
- **Zero-friction capture, semantic search, project memory, and MCP-based knowledge retrieval for AI CLI tools.**
3
+ **Capture AI CLI work, find it later, and retrieve project context when you need it.**
4
4
 
5
5
  ---
6
6
 
7
7
  ## 1. Overview
8
8
 
9
- ph is a transparent observability and knowledge layer for AI CLI tools (Claude Code, Codex CLI, Gemini CLI, OpenCode, etc.). It automatically records every prompt+response into a local SQLite database with full-text search, semantic vector search, LLM-based analysis, Git context snapshots, session grouping, and an interactive TUI browser.
9
+ ph is a local history and project-context tool for AI CLI work. It records interactions through native hooks or by wrapping a tool, then helps you search history and retrieve project context from the terminal.
10
10
 
11
- **Core principle:** ph captures conversations without changing the normal tool workflow. Optional analysis turns captured history into project summaries and memories that can be searched locally or requested by an MCP client. Capture and full-text search work without an LLM provider; analysis, embeddings, and semantic search require the configured provider.
12
-
13
- In the TUI, `p` runs the selected prompt through one of the configured Wise analysis providers (same provider/model/URL settings shown by `ph config show`) and saves the response to history. `r` reruns the prompt with its original CLI tool.
11
+ **Core principle:** ph captures conversations without changing the normal tool workflow. Optional analysis enriches each captured interaction with searchable summary, insights, decisions, and classification. Analysis does not promote active project memories; `ph close` and MCP `save_decision` are the explicit promotion paths. Capture and full-text search work without an LLM provider; analysis, embeddings, and semantic search require the configured provider.
14
12
 
15
13
  ### Key Features
16
14
 
@@ -19,7 +17,7 @@ In the TUI, `p` runs the selected prompt through one of the configured Wise anal
19
17
  - **LLM analysis** — role/tag/relevance classification, summary extraction, key insights, technical decisions
20
18
  - **Project memory** — per-project accumulated knowledge with deduped insights and decisions
21
19
  - **MCP server** — tools for agents to search memories, check project knowledge, get context
22
- - **Interactive TUI** — browse, filter, edit, star, re-run, export prompts
20
+ - **Plain-text CLI** — the everyday interface is a small set of terminal commands
23
21
  - **Session grouping** — automatic conversation grouping with cohesion scoring
24
22
  - **Git context** — records branch, modified files, and diff at capture time
25
23
  - **Background analysis** — async LLM processing after each capture (optional)
@@ -100,18 +98,41 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
100
98
 
101
99
  ---
102
100
 
103
- ## 4. CLI Commands
101
+ ## 4. Everyday Commands
104
102
 
105
103
  | Command | Description |
106
104
  |---------|-------------|
107
- | `ph` (no args) | Open interactive TUI browser |
105
+ | `ph` | Print the short usage guide |
106
+ | `ph setup` | Connect installed Claude Code, Codex CLI, Gemini CLI, and OpenCode for automatic capture |
107
+ | `ph <tool> [args...]` | Run an AI CLI tool and capture the interaction |
108
+ | `ph search <query>` | Find earlier work in the current project (five matches by default) |
109
+ | `ph show <id>` | Inspect the complete prompt, response, capture metadata, and analysis |
110
+ | `ph show <id> --json` | Print the complete interaction as JSON |
111
+ | `ph context "task"` | Retrieve project knowledge and related prompts |
112
+ | `ph close` | Review the last three hours and approve useful project knowledge |
113
+
114
+ `ph setup` is the recommended first step for everyday use. It detects installed supported tools (Claude Code, Codex CLI, Gemini CLI, and OpenCode), installs their native capture integrations, preserves existing settings, and reports whether each integration was installed or already configured. Pass tool names to choose explicitly. After setup, keep using your AI CLI normally; `ph search "query"` is the main command for retrieving earlier work. `ph <tool>` remains as a wrapper alternative.
115
+
116
+ `ph search "query"` searches the project detected from the current directory and returns five matches by default, ordered by text relevance. Use `--limit <n>` to show more, or `--all` to search across every project. When no project can be detected, PH searches all saved work and labels that scope. Searches with no current-project matches explain how to broaden the search.
117
+
118
+ `ph prepare "task"` remains as a compatibility alias for task-aware `ph context`.
119
+ `ph browse` is a compatibility alias for a plain-text list of recent interactions.
120
+ Use `ph help --all` for maintenance and integration commands, including `ph status` for recent capture and background-work state.
121
+
122
+ ## 4a. Advanced Command Reference
123
+
124
+ | Command | Description |
125
+ |---------|-------------|
126
+ | `ph` (no args) | Print the short everyday-use guide |
108
127
  | `ph <tool> [args...]` | Wrapper mode — run tool + capture |
109
- | `ph search [query]` | Full-text search prompts |
128
+ | `ph search [query]` | Full-text search (current project, five matches by default) |
110
129
  | `ph search --semantic <query>` | Semantic (vector) search |
111
130
  | `ph search --archive` | Search archived prompts |
112
- | `ph search -i <query>` | Open results in interactive TUI |
113
131
  | `ph last [n]` | Show last N prompts |
114
- | `ph context [query]` | Get RAG context for current project |
132
+ | `ph context [task]` | Retrieve task-aware project context; works without semantic embeddings |
133
+ | `ph prepare "<task>"` | Compatibility alias for task-aware context retrieval |
134
+ | `ph browse` | Compatibility alias for recent text results |
135
+ | `ph close [--since 3h]` | Review recent work and propose knowledge for explicit approval |
115
136
  | `ph sessions` | Group prompts into work sessions |
116
137
  | `ph timeline <project>` | Full chronological project history |
117
138
  | `ph stats` | History statistics |
@@ -122,10 +143,11 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
122
143
  | `ph cleanup --retention` | Archive old/unqualified prompts per retention policy |
123
144
  | `ph cleanup-reusability` | Cleanup by reusability score |
124
145
  | `ph star <id>` | Toggle bookmark |
125
- | `ph export <id>` | Export prompt (txt/json/md) |
146
+ | `ph export <id> [--format txt|json|md] [--archive]` | Export a complete interaction |
147
+ | `ph status` | Show recent capture, analysis, and remote-push state without content |
126
148
  | `ph import gemini|claude|opencode|codex` | Import from AI CLI history |
127
149
  | `ph log --tool <name> ...` | Direct log (hook target) |
128
- | `ph embed-all` | Generate embeddings for all prompts |
150
+ | `ph embed-all` | Generate embeddings for prompts without vectors |
129
151
  | `ph config get|set <key> <value>` | View/edit config |
130
152
  | `ph vacuum` | Compact SQLite database |
131
153
  | `ph memory-migrate` | Merge existing memories into project_summaries |
@@ -138,7 +160,6 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
138
160
  ### Search options
139
161
 
140
162
  ```
141
- -i / --interactive Open in TUI browser
142
163
  --tool <name> Filter by tool
143
164
  --project <name> Filter by project
144
165
  --language <lang> Filter by language
@@ -149,11 +170,12 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
149
170
  --archive Search archived prompts
150
171
  --since YYYY-MM-DD Start date
151
172
  --until YYYY-MM-DD End date
152
- --limit <n> Max results (default 50)
173
+ --limit <n> Max results (default 5)
174
+ --all Search across all projects instead of the current project
153
175
  --top Quality >= 8
154
176
  --min-quality <n> Min quality (0-10)
155
177
  --min-relevance <n> Min relevance (0-10)
156
- --full Show full prompt text
178
+ --full Show full prompt and response text
157
179
  ```
158
180
 
159
181
  ### Context options
@@ -185,43 +207,13 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
185
207
 
186
208
  ---
187
209
 
188
- ## 5. TUI Keybindings
189
-
190
- | Key | Action |
191
- |-----|--------|
192
- | `Up` / `Down`, `Page Up` / `Page Down` | Navigate list |
193
- | `Tab` | Switch pane (wide mode) |
194
- | `1`, `2`, `3` | Switch prompt/response/memory tab |
195
- | `y` | Copy to clipboard |
196
- | `s` | Toggle star |
197
- | `e` | Edit metadata |
198
- | `r` | Rerun prompt (edit before launch) |
199
- | `Shift+C` | Chat mode: launch tool with project context |
200
- | `x` | Delete entry |
201
- | `/` | Search |
202
- | `o` | Settings panel (toggle auto-analysis, view config) |
203
- | `f` | Filter panel (flat list, Enter toggle, letter jump) |
204
- | `c` | Clear all filters |
205
- | `q` / `Escape` | Quit / back |
206
-
207
- ### TUI components
208
-
209
- - **SearchBar** — always visible spotlight bar at top
210
- - **FilterPanel** — flat scrollable list of filter options with counts `[N]`, toggle with Enter, jump by letter
211
- - **SettingsView** — config viewer/editor (auto-analysis toggle, ollama URL/model, filters)
212
- - **PreviewPane** — three tabs (prompt/response/memory). Memory tab shows project-level knowledge
213
- - **ListEntry** — role marker, analysis status, star, Q/R badges, optional summary line
214
- - **Footer** — context-sensitive hints (shows `C:chat` only when entry has project)
215
-
216
- ---
217
-
218
- ## 6. Project Memory System
210
+ ## 5. Project Memory System
219
211
 
220
212
  ph maintains two levels of per-project knowledge:
221
213
 
222
- ### 6a. `project_summaries` (curated, 1 row per project)
214
+ ### 5a. `project_summaries` (curated, 1 row per project)
223
215
 
224
- Accumulated knowledge with deduped insights and decisions. Updated on every analysis. Primary source for MCP tools.
216
+ Accumulated, explicitly promoted knowledge with deduped insights and decisions. Updated by approved `close` proposals, MCP `save_decision`, and legacy migration; automatic analysis does not write here.
225
217
 
226
218
  ```bash
227
219
  # View accumulated project knowledge
@@ -231,9 +223,29 @@ ph context --project myproject
231
223
  # get_project_summary(project: "myproject")
232
224
  ```
233
225
 
234
- ### 6b. `memories` (append-only timeline)
226
+ ### 5b. `memories` (append-only timeline)
227
+
228
+ Legacy append-only project knowledge records retained for detailed audit. New automatic analysis results stay on their source interaction instead of creating memory rows.
229
+
230
+ ### Operational workflow: retrieve, work, review
235
231
 
236
- Full chronological history of every analysis run. Preserved for detailed audit.
232
+ ```bash
233
+ # Read-only task context; project auto-detected from the current directory
234
+ ph context "add Wise provider" --limit 5 --budget 3500
235
+
236
+ # Inspect the selection without calling an LLM
237
+ ph close --dry-run --since 3h
238
+
239
+ # Generate knowledge proposals; approve, edit, skip, or quit each one
240
+ ph close --since 3h
241
+ ph close --from 1670 --to 1682 --project ph
242
+ ```
243
+
244
+ `context` uses the task as a semantic retrieval query and prints source-linked prompt and memory excerpts. If Ollama embeddings are unavailable, it labels the fallback to recent project context. Retrieval never writes to SQLite. `prepare` remains an alias for compatibility. The character budget limits retrieved content; when the source list itself is larger than the budget, source IDs take precedence and the output can exceed the requested budget.
245
+
246
+ `close` selects prompt/response pairs within one project, displays them before generation, and asks the configured analysis provider for durable proposals. It checks for a terminal before making that provider call. Each accepted proposal creates an append-only memory tied to its source prompt IDs; the approved batch and summary updates are committed in one SQLite transaction. A persistence failure rolls back the whole batch. Provider errors, malformed output, dry-run, skipping, and quitting do not promote unapproved knowledge.
247
+
248
+ MCP `check_project_knowledge` uses the same retrieval and rendering boundary. MCP `save_decision` accepts optional `promptIds` and rejects missing or cross-project sources.
237
249
 
238
250
  ### Memory migration
239
251
 
@@ -245,7 +257,7 @@ ph memory-migrate # one-time: merge all memories into project_summaries
245
257
 
246
258
  ---
247
259
 
248
- ## 7. Retention & Archiving
260
+ ## 6. Retention & Archiving
249
261
 
250
262
  Configurable auto-archiving to keep the database lean:
251
263
 
@@ -268,9 +280,9 @@ ph search --archive
268
280
 
269
281
  ---
270
282
 
271
- ## 8. Background Analysis
283
+ ## 7. Background Analysis
272
284
 
273
- When enabled, every `ph log` automatically spawns a detached child process that analyzes the new entry (role, tags, relevance, summary, key insights, technical decisions).
285
+ When enabled, every `ph log` marks analysis pending and starts a detached child process that adds role, tags, relevance, summary, key insights, and technical decisions to the interaction. It does not create project memories or summaries. `ph status` shows pending, complete, or safe failure state. Remote push status is shown when configured.
274
286
 
275
287
  ```bash
276
288
  ph config set background-analysis true
@@ -318,7 +330,7 @@ credentials. `ph models mlx-serve` marks entries `[loaded]` or `[unloaded]`.
318
330
 
319
331
  ---
320
332
 
321
- ## 9. MCP Server
333
+ ## 8. MCP Server
322
334
 
323
335
  ph exposes an MCP (Model Context Protocol) server over stdio for AI agents:
324
336
 
@@ -344,26 +356,30 @@ ph mcp
344
356
 
345
357
  ---
346
358
 
347
- ## 10. HTTP Server & Remote Sync
359
+ ## 9. HTTP Server & Remote Sync
348
360
 
349
361
  Share prompt history across machines:
350
362
 
351
363
  ```bash
352
- # Start server
353
- ph server --port 3001 --host 0.0.0.0
354
-
355
- # From another machine
364
+ # Configure the required server key, then start on loopback
365
+ ph config set remote-api-key "$PH_REMOTE_API_KEY"
366
+ ph server --port 3001
367
+
368
+ # On the server, expose the listener only on a protected interface and put TLS
369
+ # in front of it before using the endpoint across an untrusted network.
370
+ # On each client, set the server URL and the same key:
371
+ ph config set remote-api-key "$PH_REMOTE_API_KEY"
356
372
  ph config set remote-url http://server-ip:3001
357
- ph remote push # send local unsynced prompts
358
- ph remote pull # fetch remote prompts
373
+ ph remote push # resumable ID-based sync
374
+ ph remote pull # resumable ID-based sync
359
375
  ph remote status # show sync state
360
376
  ```
361
377
 
362
- Every `ph log` auto-pushes to remote if configured (fire-and-forget, never blocks).
378
+ The server requires a key before it starts, binds to `127.0.0.1` by default, and exposes only a status value at public `/health`. All data routes require Bearer authentication. Push and pull cursors are scoped to the remote target and the local database UUID. Push pages are split to stay below the 32 MiB request-body limit; interrupted pages can be retried safely. Bulk push waits at a live wrapper record and continues after the response is saved. `ph log` and both wrapper modes push after capture; requests time out after five seconds so an unavailable server cannot hang the command indefinitely. An invalid optional remote URL marks sync failed while the interaction remains saved locally and the wrapped CLI still runs. Current limitation: replacing the remote database behind the same URL is not detected, and last-push/pull status times are global across targets.
363
379
 
364
380
  ---
365
381
 
366
- ## 11. Database
382
+ ## 10. Database
367
383
 
368
384
  **Location:** `~/.prompt_history.db` (configurable via `ph config set db-path`)
369
385
 
@@ -384,12 +400,12 @@ Every `ph log` auto-pushes to remote if configured (fire-and-forget, never block
384
400
  ph vacuum # compact DB
385
401
  ph cleanup # remove short/trivial/duplicate prompts
386
402
  ph cleanup --retention # archive per retention policy
387
- ph embed-all # (re)generate all embeddings
403
+ ph embed-all # generate vectors for prompts without embeddings
388
404
  ```
389
405
 
390
406
  ---
391
407
 
392
- ## 12. Filter Pipeline
408
+ ## 11. Filter Pipeline
393
409
 
394
410
  Before saving, ph filters out:
395
411
 
@@ -408,7 +424,7 @@ ph config set filter-min-relevance 3
408
424
 
409
425
  ---
410
426
 
411
- ## 13. Configuration (`~/.ph_config.json`)
427
+ ## 12. Configuration (`~/.ph_config.json`)
412
428
 
413
429
  | Key | Default | Description |
414
430
  |-----|---------|-------------|
@@ -431,8 +447,8 @@ ph config set filter-min-relevance 3
431
447
  | `retentionMinRelevance` | `3` | Archive prompts below this relevance |
432
448
  | `remoteUrl` | — | Remote ph server URL (or `PH_REMOTE_URL` env) |
433
449
  | `remoteApiKey` | — | Remote server API key |
434
- | `remoteLastPush` | — | Timestamp of last successful push |
435
- | `remoteLastPull` | — | Timestamp of last successful pull |
450
+ | `remoteLastPush` | — | Global timestamp of last successful push |
451
+ | `remoteLastPull` | — | Global timestamp of last successful pull |
436
452
 
437
453
  Provider API credentials are environment-only: `OPENROUTER_API_KEY` and
438
454
  `MLX_SERVE_API_KEY` (`GLB_OMLX_API_KEY` is a fallback). They are not written to
@@ -440,7 +456,7 @@ Provider API credentials are environment-only: `OPENROUTER_API_KEY` and
440
456
 
441
457
  ---
442
458
 
443
- ## 14. Architecture
459
+ ## 13. Architecture
444
460
 
445
461
  ```
446
462
  Hook/Import → ph log → prompts table (FTS5 indexed)
@@ -473,14 +489,13 @@ src/
473
489
  filter/ # Capture-time filter pipeline
474
490
  mcp/server.ts # MCP stdio server
475
491
  server/index.ts # HTTP REST server (zero deps)
476
- ui/ # React/Ink TUI, including extracted filter policy and panel
477
492
  importer/ # Gemini/Claude/OpenCode/Codex history importers
478
493
  hooks/ # Shell scripts and plugins for AI tools
479
494
  ```
480
495
 
481
496
  ---
482
497
 
483
- ## 15. Importing Existing History
498
+ ## 14. Importing Existing History
484
499
 
485
500
  ```bash
486
501
  # Import from Claude Code
@@ -504,7 +519,7 @@ ph import codex
504
519
 
505
520
  ---
506
521
 
507
- ## 16. Versioning and Releases
522
+ ## 15. Versioning and Releases
508
523
 
509
524
  Use Conventional Commits to describe changes: `feat:` requests a minor release,
510
525
  `fix:` requests a patch release, and `BREAKING CHANGE:` requests a major release.