docs: make the project directory the unit, and MCP a read-only window - #5
Conversation
Three decision records, and the plan they rewrite. 0013 replaces the workspace container with a plain project directory opened by `ow` in its scope, moves wiki reads onto the filesystem the harness already has open, and leaves MCP one job: consulting another project, read-only, over stdio, with no port and no token. It supersedes 0003 — four of that record's seven operative clauses are void — and narrows 0002, which keeps everything but the container. 0014 puts everything except audio capture in TypeScript and makes the CLI the product's spine, resolving 0010 by applying its own reasoning: that record disclaimed its performance argument, and what remains of it is agnostic of language. 0015 settles where the page convention lives — skills scaffolded by `ow init`, not a generated CLAUDE.md — and states the ageing that scaffolding reintroduces. Reviewed before opening: a first draft claimed a PreToolUse hook cannot see the content it is about to allow, which made the write gate look unrebuildable. It receives the complete tool_input and can deny with a reason, so refusal survives for the file tools; what does not survive is coverage of writes made through the shell. Four documents were corrected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C9Vv5jJqcGxrStXhLwbf9b
📝 WalkthroughWalkthroughThe PR establishes project directories as the application scope, adopts TypeScript and Node except for audio capture, defines scaffolded skills, and updates ADRs, plans, glossary, stack, and Claude Code plugin documentation. ChangesProject architecture and convention
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 14
🧹 Nitpick comments (1)
docs/wiki/claude-code-plugins.md (1)
168-173: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPin the Claude Code hook contract used by task 9.5.
The write gate depends on the exact
PreToolUseinput and denial response.v2.1.xis a moving range. Record the minimum supported version and fallback behavior, or verify this contract in CI.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/wiki/claude-code-plugins.md` around lines 168 - 173, Update the task 9.5 Claude Code hook documentation to pin the minimum supported version instead of relying on the moving v2.1.x range, and document the fallback behavior when the required PreToolUse contract is unavailable. Alternatively, add CI verification for the complete tool_input and permissionDecision: deny behavior described in the write gate section.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.gitignore:
- Around line 144-146: Remove the .claude/ and CLAUDE.md entries from the ignore
rules so project-scaffolded skills and shared conventions are committed and
available to every clone. Do not add a CI or release prerequisite unless task
1.4 is explicitly being implemented in this change.
In `@docs/adr/0013-the-project-directory-is-the-unit.md`:
- Around line 109-111: Update the credential claim in the ADR text near “the
application holds exactly one secret again” to say the application holds at most
one secret, and qualify that the transcription credential is held only when a
remote transcription provider is selected; preserve the reference to ADR 0003
and adr:0007.
- Around line 48-50: Specify the code fence language for the ow mcp command by
changing the unlabeled fence to a console or text fence, preserving the command
content.
In `@docs/adr/0015-the-convention-ships-as-skills.md`:
- Around line 55-68: Update the ADR roadmap to include a skill upgrade path
addressing version drift: add a generated-skill version marker, have ow init
detect and report stale skills without overwriting user edits, and provide a
user-controlled upgrade mechanism such as a reviewable diff or
confirmation-based update.
In `@docs/glossary.md`:
- Line 33: Update the glossary blockquote near the reported location to keep it
continuous: remove the blank line or prefix it with `>` so markdownlint rule
MD028 passes.
- Around line 34-39: Update the final sentence of the glossary entry for
workspace to prohibit the term only when referring to project scope or the
former user-facing domain concept. Explicitly allow established technical
repository terminology such as “pnpm workspace” and “pnpm workspaces,” while
preserving the historical ADR exception.
- Line 16: Update the recording layout in plans/open-wiki.md to include
timemap.json, matching the path defined in docs/glossary.md and referenced by
tasks 4.3, 4.7, and 4.11; keep the naming consistent across all documentation.
In `@docs/stack.md`:
- Around line 21-22: Update the Groq whisper-large-v3-turbo description to cite
a dated source for the approximately US$0.04-per-hour cost and 228x real-time
benchmark, including the benchmark context; if no suitable source is available,
remove the numerical claims and retain only the qualitative rationale.
In `@docs/wiki/claude-code-plugins.md`:
- Around line 3-6: Revise the introduction and component table in the Claude
Code plugins documentation so they do not claim this product’s plugin includes
or carries the written convention/skills. Reflect ADR 0015 and task 10.6: the
plugin should describe only its supported generic capabilities and actual
contents, while `ow init` scaffolds the product skills into the project.
In `@plans/open-wiki.md`:
- Line 86: Update the `.state/` entry in the documentation to describe it as
recovery history containing snapshots of prior pages that may retain prior or
unredacted content, rather than classifying it as non-content. Preserve the
explicit requirement that `.state/` is ignored by default.
- Around line 74-90: Update the fenced directory-layout block in the plan so its
opening fence declares the text language, resolving markdownlint MD040 while
preserving the layout content unchanged.
- Line 197: Revise task 9.1 so the project access functionality is split into a
read-only core containing read, search, and validate, and a separate
write-capable module containing write. Ensure the MCP process imports only the
read-only core, while the application and CLI may use the write-capable module.
- Line 209: Update task 9.13 in plans/open-wiki.md to explicitly require a
restrictive named-pipe ACL where supported and rejection of unauthenticated
local listeners, while preserving the existing local-socket read/validate-only
and standalone-equivalence requirements.
- Line 104: Update the project-directory workflow described in item 2.1 so
existing project directories are accepted in open mode, with validation of the
expected project layout. Restrict refusal of occupied directories to create
mode, while preserving scaffolding of raw/, wiki/, and .state/ when creating a
new project.
---
Nitpick comments:
In `@docs/wiki/claude-code-plugins.md`:
- Around line 168-173: Update the task 9.5 Claude Code hook documentation to pin
the minimum supported version instead of relying on the moving v2.1.x range, and
document the fallback behavior when the required PreToolUse contract is
unavailable. Alternatively, add CI verification for the complete tool_input and
permissionDecision: deny behavior described in the write gate section.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f679b204-2070-4a65-ac4f-898048cbd838
📒 Files selected for processing (12)
.gitignoredocs/adr/0003-mcp-as-the-only-bridge-to-the-llm.mddocs/adr/0010-a-derived-index-engine-behind-a-cli.mddocs/adr/0013-the-project-directory-is-the-unit.mddocs/adr/0014-typescript-everywhere-except-audio-capture.mddocs/adr/0015-the-convention-ships-as-skills.mddocs/glossary.mddocs/stack.mddocs/wiki/changelog.mddocs/wiki/claude-code-plugins.mddocs/wiki/index.mdplans/open-wiki.md
|
|
||
| .claude/ | ||
| CLAUDE.md No newline at end of file |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Do not ignore the project convention if it must be shared.
These entries exclude .claude/skills/ and CLAUDE.md, but the documented model says project-scaffolded skills reach everyone who clones the project. Until task 1.4 runs, this repository cannot provide reproducible convention or scc validation. Remove these rules in this change, or make task 1.4 a release prerequisite with a CI check.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.gitignore around lines 144 - 146, Remove the .claude/ and CLAUDE.md entries
from the ignore rules so project-scaffolded skills and shared conventions are
committed and available to every clone. Do not add a CI or release prerequisite
unless task 1.4 is explicitly being implemented in this change.
| ``` | ||
| ow mcp --project fenix --read-only | ||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Specify the code fence language.
markdownlint reports MD040 for Line 48. Use console or text.
Proposed fix
-```
+```console📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ``` | |
| ow mcp --project fenix --read-only | |
| ``` |
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)
[warning] 48-48: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/adr/0013-the-project-directory-is-the-unit.md` around lines 48 - 50,
Specify the code fence language for the ow mcp command by changing the unlabeled
fence to a console or text fence, preserving the command content.
Source: Linters/SAST tools
| Because the token is gone, the application holds **exactly one secret again**, the | ||
| transcription credential. That is what 0003 claimed and what | ||
| `adr:0007-plaintext-credentials-in-the-config` had to walk back to two. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Use “at most one secret” for the credential claim.
The plan and docs/stack.md allow local whisper.cpp, which requires no credential. State that the transcription credential is the only secret the application may hold when a remote provider is selected.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/adr/0013-the-project-directory-is-the-unit.md` around lines 109 - 111,
Update the credential claim in the ADR text near “the application holds exactly
one secret again” to say the application holds at most one secret, and qualify
that the transcription credential is held only when a remote transcription
provider is selected; preserve the reference to ADR 0003 and adr:0007.
| **Generating into the project reintroduces the ageing the skill was supposed to avoid.** | ||
| The plan's argument against the generated `CLAUDE.md` was that it is "a copy per folder that | ||
| ages from the moment it is written", and a skill written by `ow init` is a copy per folder | ||
| that ages from the moment it is written. Refusing to overwrite is right — the user edits | ||
| these files and losing that is worse — but it means a project scaffolded at v0.3 keeps a v0.3 | ||
| convention forever, silently, while the validators enforce v0.7. | ||
|
|
||
| ## The question this record does not answer | ||
|
|
||
| **How a scaffolded skill learns it is old.** A version marker in the generated file plus an | ||
| `ow init` that reports staleness instead of overwriting is the obvious shape, and there are | ||
| others: a skill thin enough to be a pointer at a CLI command that carries the authoritative | ||
| text, or an upgrade path that diffs and asks. Nothing here chooses, and until something | ||
| does, the ageing above is unmitigated rather than accepted. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Add a skill upgrade path before accepting silent ageing.
A project scaffolded at v0.3 can retain v0.3 instructions while validators enforce v0.7. The ADR states that this risk is unmitigated. Add a version marker, staleness check, and user-controlled upgrade path to the roadmap.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/adr/0015-the-convention-ships-as-skills.md` around lines 55 - 68, Update
the ADR roadmap to include a skill upgrade path addressing version drift: add a
generated-skill version marker, have ow init detect and report stale skills
without overwriting user edits, and provide a user-controlled upgrade mechanism
such as a reviewable diff or confirmation-based update.
| - **track** — one of the two captured streams, `mic` or `system`. Avoid: feed | ||
| - **timeline** — the two tracks merged and ordered by real time, in `timeline.json`, and written out as `timeline.vtt` for anything that reads WebVTT. Avoid: transcript | ||
| - **transcription journal** — the per-chunk record of a transcription in progress, in the recording's directory, that makes an interrupted run resumable — `adr:0012-transcription-is-a-journalled-serial-pipeline`. It is not the operation log of `.state/` and not the wiki's `log.md`. | ||
| - **time map** — the table converting an instant of the compressed audio into a real instant, in `timemap.json`. Avoid: offset table |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | grep -E '(^|/)(glossary\.md|open-wiki\.md)$|(^|/)docs/' | head -200
printf '%s\n' '--- glossary context ---'
glossary=$(git ls-files | grep -E '(^|/)docs/glossary\.md$' | head -1 || true)
if [ -n "$glossary" ]; then
cat -n "$glossary" | sed -n '1,80p'
fi
printf '%s\n' '--- open-wiki references ---'
wiki=$(git ls-files | grep -E '(^|/)plans/open-wiki\.md$' | head -1 || true)
if [ -n "$wiki" ]; then
rg -n -C 5 'time.?map|recording|canonical|4\.7|4\.11|workspace|timemap' "$wiki" || true
fi
printf '%s\n' '--- repository-wide references ---'
rg -n -i -C 2 'timemap\.json|time map|time-map|canonical recording layout|task 4\.[0-9]+|pnpm workspaces?|workspace' . --glob '!node_modules' --glob '!dist' --glob '!build' | head -400Repository: protonspy/open-wiki
Length of output: 50377
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re
glossary = Path("docs/glossary.md").read_text()
plan = Path("plans/open-wiki.md").read_text()
adr = Path("docs/adr/0006-opus-as-the-provenance-format.md").read_text()
print("glossary time-map entries:")
for i, line in enumerate(glossary.splitlines(), 1):
if re.search(r"time map|timemap\.json", line, re.I):
print(f"{i}: {line}")
print("\nrecording-layout block:")
lines = plan.splitlines()
for i, line in enumerate(lines, 1):
if "fenix/" in line:
for n in range(i, min(i + 10, len(lines) + 1)):
print(f"{n}: {lines[n-1]}")
break
print("\nrequired time-map tasks:")
for i, line in enumerate(lines, 1):
if re.search(r"time map|timemap\.json", line, re.I):
print(f"{i}: {line}")
print("\nADR 0006 time/provenance references:")
for i, line in enumerate(adr.splitlines(), 1):
if re.search(r"time map|timemap\.json|recording|opus", line, re.I):
print(f"{i}: {line}")
print("\ntracked timemap.json files:")
for path in Path(".").rglob("timemap.json"):
if any(part in {".git", "node_modules", "dist", "build"} for part in path.parts):
continue
print(path)
PYRepository: protonspy/open-wiki
Length of output: 2309
Document the time-map path consistently. plans/open-wiki.md omits timemap.json from the recording layout, although docs/glossary.md and tasks 4.3, 4.7, and 4.11 require it. Add the file to the layout or update both documents to use the chosen path.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/glossary.md` at line 16, Update the recording layout in
plans/open-wiki.md to include timemap.json, matching the path defined in
docs/glossary.md and referenced by tasks 4.3, 4.7, and 4.11; keep the naming
consistent across all documentation.
| ``` | ||
| <workspace>/ | ||
| fenix/ one project | ||
| raw/ sources, immutable once written and named for what they are | ||
| fenix-weekly-2026-07-31/ a recording, named for the occasion and its date | ||
| manifest.json · mic.opus · system.opus | ||
| timeline.json · timeline.vtt · text.md | ||
| journal.json · *.wav only until transcription seals the source | ||
| arquitetura-fenix.pdf/ an uploaded file, keeping its filename | ||
| manifest.json · source.pdf · text.md | ||
| wiki/ primary content, written by the agent and by the user | ||
| index.md · changelog.md · log.md | ||
| projects/*.md · people/*.md · topics/*.md | ||
| .state/ snapshots and operation log; not content | ||
| CLAUDE.md schema and methodology, for the agent operating the folder | ||
| atlas/ | ||
| ... | ||
| fenix/ a project — usually a repository the user already has | ||
| raw/ sources, immutable once written and named for what they are | ||
| fenix-weekly-2026-07-31/ a recording, named for the occasion and its date | ||
| manifest.json · mic.opus · system.opus | ||
| timeline.json · timeline.vtt · text.md | ||
| journal.json · *.wav only until transcription seals the source | ||
| arquitetura-fenix.pdf/ an uploaded file, keeping its filename | ||
| manifest.json · source.pdf · text.md | ||
| wiki/ primary content, written by the agent and by the user | ||
| index.md · changelog.md · log.md | ||
| projects/*.md · people/*.md · topics/*.md · codewiki/*.md | ||
| .state/ snapshots and operation log; not content | ||
| .claude/skills/ the wiki and codewiki conventions, scaffolded by `ow init` | ||
| .mcp.json other projects this one consults; never itself | ||
| CLAUDE.md short, and pointing at the skills | ||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Specify the layout fence language.
markdownlint reports MD040 for Line 74. Use text for this directory layout.
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)
[warning] 74-74: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plans/open-wiki.md` around lines 74 - 90, Update the fenced directory-layout
block in the plan so its opening fence declares the text language, resolving
markdownlint MD040 while preserving the layout content unchanged.
Source: Linters/SAST tools
| wiki/ primary content, written by the agent and by the user | ||
| index.md · changelog.md · log.md | ||
| projects/*.md · people/*.md · topics/*.md · codewiki/*.md | ||
| .state/ snapshots and operation log; not content |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Do not classify .state/ as non-content.
.state/ contains snapshots of prior pages. Those snapshots can retain unredacted text after a redaction. Describe it as recovery history that may contain prior content, and retain the explicit default-ignore requirement.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plans/open-wiki.md` at line 86, Update the `.state/` entry in the
documentation to describe it as recovery history containing snapshots of prior
pages that may retain prior or unredacted content, rather than classifying it as
non-content. Preserve the explicit requirement that `.state/` is ignored by
default.
|
|
||
| - [ ] 2.1 (Unit) Open or create a workspace: choose the folder and refuse one already occupied by something else | ||
| - [ ] 2.2 (Unit) Create, list and rename projects, each with its own `raw/`, `wiki/`, `.state/` and `CLAUDE.md` | ||
| - [ ] 2.1 (Unit) Open or create a project in a directory: scaffold `raw/`, `wiki/` and `.state/`, and refuse a directory already occupied by something else |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Allow ow to open an existing project directory.
“Refuse a directory already occupied by something else” conflicts with the stated workflow of running ow inside an existing repository. Limit this refusal to create mode. Open mode must validate and accept an existing project layout.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plans/open-wiki.md` at line 104, Update the project-directory workflow
described in item 2.1 so existing project directories are accepted in open mode,
with validation of the expected project layout. Restrict refusal of occupied
directories to create mode, while preserving scaffolding of raw/, wiki/, and
.state/ when creating a new project.
|
|
||
| ## 9 — The CLI, MCP and the agent's contract | ||
|
|
||
| - [ ] 9.1 (Unit) A project access module — read, search, validate, write — one implementation, imported by the application, the CLI and the MCP process |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Keep the write path out of the MCP process.
Task 9.1 defines one module containing read, search, validate, and write, then imports it into MCP. ADR 0013 and task 9.8 require the MCP entrypoint not to import the write path at all. Split the read-only core from the write-capable module.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plans/open-wiki.md` at line 197, Revise task 9.1 so the project access
functionality is split into a read-only core containing read, search, and
validate, and a separate write-capable module containing write. Ensure the MCP
process imports only the read-only core, while the application and CLI may use
the write-capable module.
| - [ ] 9.10 (Unit) Announce the project in the server's name and description, so an agent with several configured says which base it answered from | ||
| - [ ] 9.11 (Unit) `ow search` and `ow graph`: the lexical and structural queries over the local project that `adr:0013-the-project-directory-is-the-unit` sends to the CLI rather than to MCP, printing JSON | ||
| - [ ] 9.12 (Unit) A validation error readable enough for the agent to fix it on its own and try again — the same text whether it came from the CLI, a hook or the editor | ||
| - [ ] 9.13 (TDD) Pay down cold start: bundle the CLI to a single file, and talk to the running application over a local socket when there is one — the socket carries read and validate and never write, and the standalone path produces the same answer |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Carry the local-socket security constraint into task 9.13.
ADR 0013 requires a restrictive named-pipe ACL where available and rejects unauthenticated local listeners. Add those transport and access-control requirements here. “Read and validate, never write” alone does not prevent the loopback exposure from returning.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plans/open-wiki.md` at line 209, Update task 9.13 in plans/open-wiki.md to
explicitly require a restrictive named-pipe ACL where supported and rejection of
unauthenticated local listeners, while preserving the existing local-socket
read/validate-only and standalone-equivalence requirements.
…k contract again A validation pass over plans/open-wiki.md, then a review of the fixes. The architecture hole was group 5: the preamble said every write goes through the validated store, but nothing said which caller does what, so the automatic fields, the log and the index had no executor on the path the agent actually uses. The preamble now divides one module across three callers — editor and CLI verb, the hook pair, the folder observer — and 9.5 builds both hooks rather than only PreToolUse. Second correction to the same fact in two commits: a PreToolUse hook can return updatedInput and rewrite the arguments before the tool runs. So the store does not merely refuse on the direct path, it completes — the fields filled on the agent's behalf are written into the input rather than demanded back in an error. The first commit said the hook cannot see the content; a draft of this one said it cannot change it. Both were reasoned about rather than read, and the plan now says so where the claim lives. Other holes closed: supersession was prose-only, so `ow graph superseded` had nothing to walk (new 5.2, and the glossary entry it contradicted); 8.12 and 9.3 disagreed about whether changing the content language rewrites a scaffolded file, and the first fix traded that contradiction for a hole where nothing put the language in front of the agent at all; three tasks scaffolded a project and produced different projects depending on the door; nothing wrote the consulting .mcp.json, leaving the paste step the pivot claimed to have removed (new 9.8); raw/_inbox sat inside the immutable tree with no exemption; index.md, changelog.md and log.md were about to be validated against the entity schema. ADR 0009 stops citing a task number that had already rotted twice, 0014 says why 0010 is marked superseded rather than rejected and answers the ordering question 0010 left open, and the Methods note stops being a roll-call that was already missing six tasks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C9Vv5jJqcGxrStXhLwbf9b
Second pass — validation of the plan, and the holes it foundReviewed The architecture holeGroup 5's preamble said every write goes through the validated store, but nothing said which caller does what. On the path the agent actually uses, the automatic fields (5.5), the log and changelog (5.6) and the index (5.7) had no executor at all. The preamble now divides one module across three callers — editor and CLI verb, the hook pair, the folder observer — and 9.5 builds The hook contract, wrong a second timeThe first commit recorded that a Both errors came from reasoning about the contract instead of reading it, so the plan and ADR 0013 now say so at the place the claim lives. What genuinely does not survive is coverage of writes made through the shell, which stays 9.5's problem. Other holes closed
Also: ADR 0009 stops citing a task number that had rotted twice; 0014 explains why 0010 is marked Still open, unchangedThe write gate's composition (9.5), and what of |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plans/open-wiki.md`:
- Line 211: Update task 8.12 in the project plan by changing “afterwards” to the
American English spelling “afterward”; leave the rest of the task text
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: fe997656-446c-42a3-ad73-27fd11edb3b2
📒 Files selected for processing (8)
docs/adr/0009-distribution-through-github-releases.mddocs/adr/0013-the-project-directory-is-the-unit.mddocs/adr/0014-typescript-everywhere-except-audio-capture.mddocs/adr/0015-the-convention-ships-as-skills.mddocs/glossary.mddocs/wiki/changelog.mddocs/wiki/claude-code-plugins.mdplans/open-wiki.md
🚧 Files skipped from review as they are similar to previous changes (6)
- docs/adr/0015-the-convention-ships-as-skills.md
- docs/glossary.md
- docs/wiki/claude-code-plugins.md
- docs/adr/0014-typescript-everywhere-except-audio-capture.md
- docs/adr/0013-the-project-directory-is-the-unit.md
- docs/wiki/changelog.md
| - [ ] 9.17 (Unit) Write the agent-facing skill **from the tool list 9.7–9.10 actually shipped**, and settle in the same task whether it or the `CLAUDE.md` of 9.14 is the single home of the convention | ||
| - [ ] 8.10 (Unit) Watch the folder and reflect changes on screen live, whichever wrote them — the agent, a hook, or the user in another editor | ||
| - [ ] 8.11 (Unit) An operation history with undo, fed by 2.4, and honest about covering only what was observed | ||
| - [ ] 8.12 (Unit) Choose the content language at onboarding and change it afterwards — English by default, Brazilian Portuguese and Spanish alongside it — held in the project settings of 2.7 and reaching exactly two places: the transcription hint of 4.15, and the generated `CLAUDE.md` of 9.4, which is regenerated on change because it is generated and the skills are not |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use the American English spelling.
Change afterwards to afterward in task 8.12.
🧰 Tools
🪛 LanguageTool
[locale-violation] ~211-~211: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...nt language at onboarding and change it afterwards — English by default, Brazilian Portugu...
(AFTERWARDS_US)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plans/open-wiki.md` at line 211, Update task 8.12 in the project plan by
changing “afterwards” to the American English spelling “afterward”; leave the
rest of the task text unchanged.
Source: Linters/SAST tools
Three decision records, and the plan they rewrite. Documentation only — there is no source in this repo yet.
What changed
adr:0013-the-project-directory-is-the-unit— the pivot. A project is a directory, opened byowin its scope the waycode .works; there is no workspace container. The harness reads the wiki off the filesystem it already has open, so MCP keeps one job: consulting another project, read-only, over stdio, spawned by the harness. No port, no token, whole pages rather than passages, and no embeddings.It supersedes
adr:0003— four of that record's seven operative clauses are void (HTTP on the loopback started by the app, MCP exposing ingest and write, the project chosen by the application, the mandatory token); three survive and are its substance (the app calls no LLM, the agent writes, write-time validation replaces the writer). It narrowsadr:0002, which loses the container and keeps everything else.adr:0014-typescript-everywhere-except-audio-capture— Rust keeps the recorder and nothing else; the CLI is the product's spine and ships to npm as well as in the installer. Supersedesadr:0010by applying its own reasoning: that record explicitly disclaimed its performance argument, and what remained is agnostic of language.adr:0015-the-convention-ships-as-skills—ow initscaffolds the wiki and codewiki conventions into.claude/skills/, never overwriting. Settles the question the plan had left open since the beginning, and states the ageing that scaffolding into a project reintroduces.plans/open-wiki.mdwas rewritten around all three — group 9 went from an HTTP server with a token to a CLI plus a read-only stdio server, and groups 2, 8 and 10 followed. Glossary, stack,claude-code-pluginsand the wiki index were brought in line.How it was verified
npx @protonspy/scc validate— exit 0, no findings.No tests or lint were run:
apps/andpackages/do not exist yet (task 1.1 is unstarted), so there is no suite and nothing to lint. The change touches only markdown.A
code-reviewand asecurity-reviewpass ran on the diff before this PR, and both found substantive things. The most important:PreToolUsehook cannot see the content it is about to allow, which made the write gate look unrebuildable and drove ADR 0013's central consequence. It receives the completetool_input—contentforWrite, the strings forEdit— and can answerpermissionDecision: denywith a reason. Refusal survives intact for the file tools. What does not survive is coverage: a write made through Bash carries a command string, anddeny Edit(wiki/**)does not constrain Bash, because permission rules are per tool. Four documents were corrected and task 9.5 now has to answer for the shell..claude/,.mcp.jsonandCLAUDE.mdare executable configuration living in the project directory. A write path reaching them edits away its own restraint, through a change that reads as documentation in review. Now stated in 0013 and enforced by new task 9.6.raw/-in-git question was analysed on cost, not on disclosure. It weighed 11 MB against a link resolving, and never against the fact that committing recorded meeting audio puts it in every clone and fork permanently — dissolving the promisestack.mdmakes for whisper.cpp..state/is worse: it holds every page as it was before each write, so a redaction survives there. The open question now names both, and the default is deny (new task 2.8).Decisions left open, deliberately
Written as open questions inside the records, in the house style of
adr:0010:raw/and.state/enters git, on the disclosure axis rather than the size one.adr:0015).One thing this PR does not fix
.claude/andCLAUDE.mdare in.gitignore, so the methodology and thesccmanifest exist only on the author's machine —scc validatecannot run in a worktree, in CI, or for anyone who clones. It is already task 1.4 and it blocked verification here until the files were copied in by hand. Worth doing before the next PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01C9Vv5jJqcGxrStXhLwbf9b
Summary by CodeRabbit
Documentation
Chores