{"content": "todo 1 next", "meta": {"from": "journal"}}
{"content": "rule 40 \u2014 A feature is named for what it is, never for its machinery \u2014 Messages 599, 600 and 703. A feature is a capability the user would name and would think of switching off. File tracking, a write gate, a phrase bank, a tree diff are services used inside a feature, not features of their own: they live in the feature they serve. Before adding a directory under features/, say what the user would call it; if the answer names a mechanism, it belongs inside something else. Report 16 holds the grouping this implies.", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.; that Edit call returned 23,151 characters, the largest this session \u2014 It stays in the context for good. If you were looking for one thing in it, the next read can be narrower: grep for the line, sed a range, head the file.", "meta": {"from": "journal"}}
{"content": "fact 9 \u2014 Every public method on a controller becomes a journal command \u2014 The CLI is generated from the controllers: each public method of Controller, or of a typed controller, turns into journal <noun> <method>. A helper added to the base class therefore becomes a command on every type \u2014 which is how journal <type> handled and journal <type> refuse came to exist, from the CRUD funnel and the refusal funnel. An internal helper on a controller is named with a leading underscore, as _shaped and _status already are, or it ships as a command nobody meant.; rule 41 \u2014 Keep moving, run the whole suite before every commit, never wait \u2014 The full suite runs in about seven seconds: .venv/bin/python -m pytest -q --timeout=300 -n auto. Run it before every commit instead of picking tests by name. Group rows that sit in the same code into one sitting: write them all, test once, commit once. And never wait, not for a subagent, a build, or an answer you can carry on without. Dispatch it and keep working. If you truly are waiting on something, say so in the work log.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 3 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 3 judged files since the last commit. Consider running `commandments judge --changes` to confirm they conform, and fix any sin at its SOURCE (don't launder a finding with a default/cast/null-check). This is a one-time nudge for this batch \u2014 if you've already judged, or these changes aren't worth a scan, just say so and carry on.; rule 35 \u2014 Write clean code - one funnel per kind of operation, never the same\u2026 \u2014 Every kind of operation has one funnel: one method that creates, one that saves, one that refuses, one that formats. A second method that does the same thing under another name splits the behaviour, and the two drift apart. Before writing a method, search for the one that already does it and extend that. scripts/checks/funnels.py finds bodies written twice.; rule 36 \u2014 Clean, DRY, idiomatic before it is committed, never after it is\u2026 \u2014 The user should never be the one who finds duplication, dead code, a clumsy name or a pattern the codebase does not use. Read the diff before every commit as a reviewer would, and fix what is not clean then, not in a follow-up after a complaint.; rule 46 \u2014 Only commit and push once the whole journal is proven to boot \u2014 Messages 2178 and 2179. A release that has not been started for real can crash every project that installs it, as 2.78.3 did for Codex and 2.84.0 did to project records. Before every commit and push: the full suite passes, including tests/test_it_boots.py, which installs a packed copy into a fresh project, launches Claude and Codex from it, writes a project record, upgrades again and checks the record survives. When a change touches launching, installing or upgrading, also start a real journal in a scratch project and close it properly afterwards, leaving no process behind.; rule 48 \u2014 The viewer is built from its component library, and pages only\u2026 \u2014 Message 4258. Every visual piece the viewer shows more than once, or that a user would recognise as the same kind of thing (a dialog, a side panel or inspector, a dropdown, a list row, a switch, a button), is one component in web/src/kit, extracted aggressively, and every page composes those components instead of building its own copy. Before writing markup or styles in a page, look for the kit component that already does it and extend it with a prop; a second hand-built version is a bug. The side panel that animated in but not out, while a separate skill panel did both, is the example.", "meta": {"from": "journal"}}
{"content": "your command ran 30s in the foreground and was moved to the background \u2014 carry on with other work; you are told when it ends. Start a command you expect to take long in the background yourself", "meta": {"from": "journal"}}
{"content": "the end tag does this in one step \u2014 [!end:N] makes the turn itself what landed; it runs only when it opens the last text of your turn; rule 37 \u2014 Close every to-do explicitly with todo done or a Journal commit\u2026 \u2014 Ending work does not close its row. A to-do is closed by journal todo done <n> --how, or by a commit whose message carries Journal: todos done <n> at column 0, several numbers separated by commas. A row left open after its work landed misleads the next session and auto mode.", "meta": {"from": "journal"}}
{"content": "fact 13 \u2014 This live session runs the installed copy in .journal/journal.pyz \u2014 The running journal (server, hooks, CLI) runs from .journal/journal.pyz with its viewer and skills in .journal/src, never from the repo. A change in the repo reaches it only through python3 src/journal.py --root .journal upgrade, which packs the zip again. A commit alone changes nothing that is running.; fact 24 \u2014 An answer followed by tool calls can be missing from Claude's\u2026 \u2014 Seen 2026-09-24 for messages 9391-9404: text blocks opening with [!reply:n] that were followed by tool calls never appeared in the session's jsonl (only thinking and tool_use rows did), so the journal never saw them and the replies were lost. When a turn goes on after answering, send the answer with journal message reply <n> \"<text>\" instead of the tag.", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"To-do 1 is closed\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead; fact 25 \u2014 A designer's install packs the whole tree, half-done server edits\u2026 \u2014 2026-09-25: Eames and Saul run python3 src/journal.py --root .journal upgrade after their viewer builds; it packs every file in src, so a server handler I was halfway through writing went live and raised on every PostToolUse hook. While designers work in parallel, keep server edits whole between tool calls (write and test in the scratchpad first), and reinstall after reverting anything.", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"nothing else open\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead; rule 45 \u2014 No prose words as names in code - said, says, heard, spoke, told\u2026 \u2014 Messages 1360 and 1698. The user has said more than once that code must not read like prose: a variable, attribute, property or function is named for what it holds or does (text, command, labels, lines), never with a verb from a story. 'says' on the Design type (1360) and 'said = call.said.lower()' in features/recital.py (1698) are the examples. Rule 27 states the naming rule; this one carries the words, so writing one of them whispers it. Before writing a name, ask whether a reader who has never seen the code would know what it holds.", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "rule 38 \u2014 Never change the git branch until the user says so, by name \u2014 The work happens on the branch the user named. That was main until message 5929 and question 80 (2026-09-23), which moved the sins work to the branch sins. Do not create, switch to or merge any other branch unless the user names it in their own words.", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 9, 10", "meta": {"from": "journal"}}
