{"content": "1 new message 17551 - answer by opening your turn with [!reply:17551]", "meta": {"from": "journal"}}
{"content": "1 new message 17553 - answer by opening your turn with [!reply:17553]", "meta": {"from": "journal"}}
{"content": "1 new message 17554 - answer by opening your turn with [!reply:17554]", "meta": {"from": "journal"}}
{"content": "1 new message 17555 - answer by opening your turn with [!reply:17555]", "meta": {"from": "journal"}}
{"content": "1 new message 17556 - answer by opening your turn with [!reply:17556]", "meta": {"from": "journal"}}
{"content": "the todo tag does this in one step \u2014 [!todo=\"the title\"] files it with the turn as its brief; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "1 new message 17557 - answer by opening your turn with [!reply:17557]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "1 new message 17558 - answer by opening your turn with [!reply:17558]", "meta": {"from": "journal"}}
{"content": "1 new message 17559 - answer by opening your turn with [!reply:17559]", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread worktrees 93, 94", "meta": {"from": "journal"}}
{"content": "helper 148, Betty Steadman, reported in message 17561 \u2014 read it, then journal helper finish 148 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "helper 145, Kira Kitwell, reported in message 17564 \u2014 read it, then journal helper finish 145 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "helper 146, Linnea Lockwood, reported in message 17566 \u2014 read it, then journal helper finish 146 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread worktree 95", "meta": {"from": "journal"}}
{"content": "helper 147, Keya Keyboard, reported in message 17569 \u2014 read it, then journal helper finish 147 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2170 stands still while todo 3136 is ready \u2014 if work 2170 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3136. Stop only when nothing ready is left.; Four footmen finishing the phone app and the main release", "meta": {"from": "journal"}}
{"content": "helper 147, Keya Keyboard, reported in message 17571 \u2014 read it, then journal helper finish 147 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "helper 147, Keya Keyboard, reported in message 17573 \u2014 read it, then journal helper finish 147 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "the tunnel server tunler.jessegall.nl answers for no address \u2014 the phone's address and share links are down until it is back; restarting here would not help, so nothing is restarted. Tell the user once.", "meta": {"from": "journal"}}
{"content": "the phone's address did not answer 1 times, so its tunnel was restarted", "meta": {"from": "journal"}}
{"content": "your last message ran its paragraphs together \u2014 a blank line between parts is what makes a message readable: one thought to a paragraph", "meta": {"from": "journal"}}
{"content": "helper 149, Morris Mergeman, reported in message 17577 \u2014 read it, then journal helper finish 149 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2170 stands still while todo 3150 is ready \u2014 if work 2170 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3150. Stop only when nothing ready is left.; Morris merging main into the phone branch; Keya's keyboard fix is committed\u2026", "meta": {"from": "journal"}}
{"content": "rule 54 \u2014 Settings and feature switches are read at boot and on change, never\u2026 \u2014 The user, message 13349: the application boots, determines every feature and setting once, and re-evaluates only when something changes, such as a setting or a plugin. Never lazy-load settings.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2170 stands still while todo 3149 is ready \u2014 if work 2170 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3149. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "the await tag does this in one step \u2014 [!await] makes the rest of the turn what you wait for; [!await on=(\"<id>\", \"helper:<n>\")] waits on those; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "the tunnel server tunler.jessegall.nl answers for no address \u2014 the phone's address and share links are down until it is back; restarting here would not help, so nothing is restarted. Tell the user once.", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "your command ran 34s 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": "your wait for The whole suite on the merged phone branch before pull request\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "rule 57 \u2014 Never merge the overnight refactor into main before its pull request\u2026 \u2014 Messages 15005, 15006, 15109, 15110 (2026-10-04): all refactor work goes on branch overnight-refactor and reaches the user as one pull request, which they read in the morning; nothing of it is merged into main until they say so. Hotfixes the user explicitly asks for go to main at once and are merged into the branch.; rule 61 \u2014 Features wait as pull requests until approved; only hotfixes merge\u2026 \u2014 Message 17118 (2026-10-06), after the overnight refactor merged as 2.252.0: start new work in a new branch, do not merge, write the pull request. Every pull request or new feature is parked until the user approves it. Hotfixes can be merged into main immediately (by a dispatched agent in a worktree of main, rule 60).", "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 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.; 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.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2170 stands still while todo 3150 is ready \u2014 if work 2170 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3150. Stop only when nothing ready is left.; 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": "helper 150, Rena Releaseworth, reported in message 17589 \u2014 read it, then journal helper finish 150 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "todo 3136, A plugin's one row per title answers a create from an interceptor\u2026 \u2014 journal todo start 3136 when it is next", "meta": {"from": "journal"}}
{"content": "request POST /api/run (todo read) is slower than its budget \u2014 109ms last (109ms of it working), against a budget of 50ms. Seen 13 times.", "meta": {"from": "journal"}}
{"content": "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": "fact 18 \u2014 cProfile inflates the slow-request profiles about tenfold \u2014 The faults feature writes a profile when a request passes its budget, and the profile is taken with cProfile, which adds per-call overhead. On 2026-09-22 /api/summary profiled at 58ms with 48ms inside Resource.fork's deep copy; with the profiler off the same call ran in 2 to 7ms. Read the profile for where the time goes in relative terms, then time the call with curl before changing anything.; rule 42 \u2014 Every user-facing text passes the formatters before it leaves the\u2026 \u2014 Not only a brief. A title, an abstract, an outcome and every section body are read by a person, so each goes through the same formatters on its way to the viewer \u2014 chat turns, activity items, to-do rows, inspector pages, docs alike. One field formatted out of five is not a rule, it is an accident, and it is how a raw tag ended up in the activity list after the tags feature had been stripping them for weeks. When a new field carries words a person reads, it joins the list in the same place.", "meta": {"from": "journal"}}
{"content": "todo 3152 next", "meta": {"from": "journal"}}
{"content": "1 new message 17594 - answer by opening your turn with [!reply:17594]", "meta": {"from": "journal"}}
{"content": "1 new message 17595 - answer by opening your turn with [!reply:17595]", "meta": {"from": "journal"}}
{"content": "1 new message 17596 - answer by opening your turn with [!reply:17596]", "meta": {"from": "journal"}}
{"content": "your last message ran its paragraphs together \u2014 a blank line between parts is what makes a message readable: one thought to a paragraph", "meta": {"from": "journal"}}
{"content": "message 17598 file Screenshot 2026-10-07 at 11.10.37.png needs tags \u2014 inspect the attachment, then journal message tag 17598 \"Screenshot 2026-10-07 at 11.10.37.png\" \"<a few words describing what it shows>\"; 1 new message 17598 - answer by opening your turn with [!reply:17598]; message 17598 updated", "meta": {"from": "journal"}}
{"content": "rule 39 \u2014 Use only registered exclamation response tags \u2014 A tag like [!reply:12] runs a command, and only the tags in the tags.runs setting are registered. An invented tag does nothing and shows as raw text in the chat. Use the registered ones (reply, log, end, todo, fact, rule) and nothing else.", "meta": {"from": "journal"}}
{"content": "1 new message 17599 - answer by opening your turn with [!reply:17599]", "meta": {"from": "journal"}}
{"content": "1 new message 17600 - answer by opening your turn with [!reply:17600]", "meta": {"from": "journal"}}
{"content": "the todo tag does this in one step \u2014 [!todo=\"the title\"] files it with the turn as its brief; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "todo 3155 next", "meta": {"from": "journal"}}
{"content": "fact 20 \u2014 A slim supervisor holds the agent and a worker reloads on every build \u2014 Since 2.118.0 (2026-09-23). src/supervisor.py is standard library only and never reloads: journal claude hands its process over to it (os.execv), and it owns the pty and the agent process, relays the terminal, writes the printed and screen captures, listens on the typist socket, restarts the agent in the same session from a relaunch command written to its runtime folder while a restart is pending, and stops it with escalation while draining the pty (an agent cannot finish exiting on macOS while its output is unread). It starts the worker (src/worker.py, which runs runner/worker.py; engine/worker.py stays as an alias for supervisors started before 2.201) and starts it again whenever it exits: RELOAD on a new build, RELAUNCH to restart the agent, STOP to end, HEAL or a quick crash to roll back a build through journal heal. The worker holds everything else: seating the session, the start-up confirm typed through the typist, services, viewer, update check, check-in, and the one-time relaunch of sessions launched before agents/terminal.py LAUNCH. agents/terminal.py holds only journal-side helpers. The server (serve.py) still runs the engines and re-execs itself on a .py change. When the agent exits, the supervisor runs journal ended, which puts set-aside hooks back and stops the server when no session is left.; fact 32 \u2014 The mobile app's pull request may be merged once it is ready \u2014 Messages 17282 and 17283 (2026-10-06): the user gave permission to merge the pull request that builds the phone app's full feature set (to-do 3054) once it is ready, without waiting for approval. Ready means: the phone app can use every feature the desktop viewer has (checked against the design's inventory of desktop places and actions, each one marked done); three critique rounds done (rule 58); built on its own branch; the whole suite and boot guard green; and reviewed by two agents with their findings fixed, as pull request 8 was. This is the user's go for rule 61 for that one pull request only.", "meta": {"from": "journal"}}
{"content": "helper 152, Ian Interceptwell, reported in message 17602 \u2014 read it, then journal helper finish 152 once its work is taken or dropped", "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.", "meta": {"from": "journal"}}
{"content": "the phone's address did not answer 1 times, so its tunnel was restarted", "meta": {"from": "journal"}}
{"content": "1 new message 17606 - answer by opening your turn with [!reply:17606]", "meta": {"from": "journal"}}
{"content": "fact 26 \u2014 Claude Code reads agent profiles when a session starts \u2014 Seen 2026-09-26: after the board-filler's profile in .claude/agents gained its steps and the Grep rule, dispatches from the running session still used the old profile (a 3.5-minute first question, shell grep refused); after the session restarted, the same request took 21 seconds with 4 calls. A change to an agent type reaches only sessions started after it is written.; 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.; 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": "todo 3156 next; 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.", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "1 new message 17610 - answer by opening your turn with [!reply:17610]", "meta": {"from": "journal"}}
{"content": "1 new message 17611 - answer by opening your turn with [!reply:17611]", "meta": {"from": "journal"}}
{"content": "1 new message 17612 - answer by opening your turn with [!reply:17612]", "meta": {"from": "journal"}}
{"content": "1 new message 17613 - answer by opening your turn with [!reply:17613]", "meta": {"from": "journal"}}
{"content": "1 new message 17614 - answer by opening your turn with [!reply:17614]", "meta": {"from": "journal"}}
{"content": "1 new message 17615 - answer by opening your turn with [!reply:17615]", "meta": {"from": "journal"}}
{"content": "1 new message 17616 - answer by opening your turn with [!reply:17616]", "meta": {"from": "journal"}}
{"content": "1 new message 17617 - answer by opening your turn with [!reply:17617]", "meta": {"from": "journal"}}
{"content": "answer message 17615 before you write anything \u2014 answer by opening your turn with [!reply:17615]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "helper 151, Tess Tunnelfree, reported in message 17619 \u2014 read it, then journal helper finish 151 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "1 new message 17620 - answer by opening your turn with [!reply:17620]", "meta": {"from": "journal"}}
{"content": "1 new message 17621 - answer by opening your turn with [!reply:17621]", "meta": {"from": "journal"}}
{"content": "suggestion 13 updated", "meta": {"from": "journal"}}
{"content": "suggestion 13 completed", "meta": {"from": "journal"}}
{"content": "helper 154, Paulo Pollsteady, reported in message 17622 \u2014 read it, then journal helper finish 154 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "question 209 completed", "meta": {"from": "journal"}}
{"content": "question 206 completed", "meta": {"from": "journal"}}
{"content": "1 new message 17624 - answer by opening your turn with [!reply:17624]", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 1 of 6 - Add the report\u2019s section headings \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:83. Lead with the answer in the report's brief, then put every part you plan on the report before writing any of them: journal report section 83 \"<part>\" \"Being written.\" for each, in order: the evidence, what was already sound, what remains uncertain. Then journal sequence next 10 --about report:83.", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 2 of 6 - Write the report\u2019s sections \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:83. Write the parts one at a time and in order with journal report section 83 \"<part>\" \"<body>\"; the user sees each one appear where you are. Then journal sequence next 10 --about report:83.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 3 of 6 - Add the document or report to a\u2026 \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:83. If a collection the user keeps fits what you wrote, add it: journal collection add <collection n> report:83. Look with journal collection all first. When none fits but other documents or reports on the same subject sit in no collection, make one named for the subject with journal collection create \"<subject>\", add this and them, and say so in one line. A row with nothing related gets no collection of its own. Then journal sequence next 10 --about report:83.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 4 of 6 - Link the items behind the\u2026 \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:83. Link the rows it answers or was built on, such as the to-dos, plans, documents, reports or messages it is about, with journal report link 83 \"<row>\" for each. Leave out rows it only mentions in passing. Then journal sequence next 10 --about report:83.", "meta": {"from": "journal"}}
{"content": "answer message 17615, message 17617, message 17620 before you write anything \u2014 answer each by opening a turn with [!reply:<n>]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "1 new message 17625 - answer by opening your turn with [!reply:17625]", "meta": {"from": "journal"}}
{"content": "1 new message 17626 - answer by opening your turn with [!reply:17626]", "meta": {"from": "journal"}}
{"content": "1 new message 17627 - answer by opening your turn with [!reply:17627]", "meta": {"from": "journal"}}
{"content": "1 new message 17628 - answer by opening your turn with [!reply:17628]", "meta": {"from": "journal"}}
{"content": "1 new message 17629 - answer by opening your turn with [!reply:17629]", "meta": {"from": "journal"}}
{"content": "1 new message 17630 - answer by opening your turn with [!reply:17630]", "meta": {"from": "journal"}}
{"content": "1 new message 17631 - answer by opening your turn with [!reply:17631]", "meta": {"from": "journal"}}
{"content": "1 new message 17632 - answer by opening your turn with [!reply:17632]", "meta": {"from": "journal"}}
{"content": "1 new message 17633 - answer by opening your turn with [!reply:17633]", "meta": {"from": "journal"}}
{"content": "1 new message 17634 - answer by opening your turn with [!reply:17634]", "meta": {"from": "journal"}}
{"content": "the todo tag does this in one step \u2014 [!todo=\"the title\"] files it with the turn as its brief; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread todo 3164", "meta": {"from": "journal"}}
{"content": "helper 153, Nadia Nudgeworth, reported in message 17639 \u2014 read it, then journal helper finish 153 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "helper 155, Vera Vocabulary, reported in message 17641 \u2014 read it, then journal helper finish 155 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "helper 157, Nell Notewell, reported in message 17644 \u2014 read it, then journal helper finish 157 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "1 new message 17647 - answer by opening your turn with [!reply:17647]", "meta": {"from": "journal"}}
{"content": "answer message 17647 before you write anything \u2014 answer by opening your turn with [!reply:17647]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "1 new message 17648 - answer by opening your turn with [!reply:17648]; report 83 updated", "meta": {"from": "journal"}}
{"content": "1 new message 17649 - answer by opening your turn with [!reply:17649]", "meta": {"from": "journal"}}
{"content": "rule 39 \u2014 Use only registered exclamation response tags \u2014 A tag like [!reply:12] runs a command, and only the tags in the tags.runs setting are registered. An invented tag does nothing and shows as raw text in the chat. Use the registered ones (reply, log, end, todo, fact, rule) and nothing else.", "meta": {"from": "journal"}}
{"content": "answer message 17649 before you write anything \u2014 answer by opening your turn with [!reply:17649]. a reply, a reaction, or journal message processed <n>; todo 3157 next", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 1260ms last (93ms of it working), against a budget of 50ms. Seen 19 times.; hook POST /api/hook/claude is slower than its budget \u2014 455ms last (51ms of it working, 4ms waiting on locks, then 668ms more after it answered), against a budget of 50ms. Seen 3075 times.", "meta": {"from": "journal"}}
{"content": "todo 3165 next", "meta": {"from": "journal"}}
{"content": "1 new message 17651 - answer by opening your turn with [!reply:17651]", "meta": {"from": "journal"}}
{"content": "todo 3170 next", "meta": {"from": "journal"}}
{"content": "work 2173, The agent shows Waiting, not Idle, while it waits on footmen or a\u2026 \u2014 it was parked because: The waiting status design waits for the user's approval. journal work resume 2173 picks it up again.", "meta": {"from": "journal"}}
{"content": "helper 156, Linnea Lockwood, reported in message 17654 \u2014 read it, then journal helper finish 156 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "work 2173, The agent shows Waiting, not Idle, while it waits on footmen or a\u2026 \u2014 it was parked because: The waiting status design waits for the user's approval. journal work resume 2173 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 17655 - answer by opening your turn with [!reply:17655]", "meta": {"from": "journal"}}
{"content": "rule 55 \u2014 Always dispatch Codex helpers on gpt-6-sol \u2014 The user's word, message 13431: switch the codex agents to GPT-6-Sol and make it their default. ~/.codex/config.toml names it as the default model too.", "meta": {"from": "journal"}}
{"content": "to-do 3179 came from message 17655? \u2014 link it: journal message process 17655 \"<their words>\" todo:3179", "meta": {"from": "journal"}}
{"content": "todo 3179 next", "meta": {"from": "journal"}}
{"content": "todo 3179 next", "meta": {"from": "journal"}}
{"content": "1 new message 17659 - answer by opening your turn with [!reply:17659]", "meta": {"from": "journal"}}
{"content": "1 new message 17660 - answer by opening your turn with [!reply:17660]", "meta": {"from": "journal"}}
{"content": "Code Commandments found 49 sins across 11 skills. \u2014 journal check show 29 says why; fix it, then journal check run 29", "meta": {"from": "journal"}}
{"content": "message 17661 file Screenshot 2026-10-07 at 12.08.41.png needs tags \u2014 inspect the attachment, then journal message tag 17661 \"Screenshot 2026-10-07 at 12.08.41.png\" \"<a few words describing what it shows>\"; 1 new message 17661 - answer by opening your turn with [!reply:17661]; message 17661 updated", "meta": {"from": "journal"}}
{"content": "helper 157, Nell Notewell, reported in message 17662 \u2014 read it, then journal helper finish 157 once its work is taken or dropped; 1 new message 17663 - answer by opening your turn with [!reply:17663]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat; 1 new message 17664 - answer by opening your turn with [!reply:17664]", "meta": {"from": "journal"}}
{"content": "question 207 completed", "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.", "meta": {"from": "journal"}}
{"content": "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.", "meta": {"from": "journal"}}
{"content": "rule 27 \u2014 Name a declaration with the word a reader already knows \u2014 An attribute, a variable or a field gets the ordinary programming word for what it holds, not an evocative one. was, heard and alone were poetry; aliases, notify_actions and urgent_actions are what they are. The test: could a reader who has never seen this codebase guess what it holds from the name alone? Prose belongs in the help text and the abstract, where it is read as prose. This does not license abbreviations \u2014 a plain word in full, not a short one.", "meta": {"from": "journal"}}
{"content": "to-do 3180 came from message 17660? \u2014 link it: journal message process 17660 \"<their words>\" todo:3180; to-do 3181 came from message 17660? \u2014 link it: journal message process 17660 \"<their words>\" todo:3181; to-do 3182 came from message 17660? \u2014 link it: journal message process 17660 \"<their words>\" todo:3182; to-do 3183 came from message 17660? \u2014 link it: journal message process 17660 \"<their words>\" todo:3183", "meta": {"from": "journal"}}
{"content": "1 new message 17666 - answer by opening your turn with [!reply:17666]", "meta": {"from": "journal"}}
{"content": "work 2173, The agent shows Waiting, not Idle, while it waits on footmen or a\u2026 \u2014 it was parked because: The waiting status design waits for the user's approval. journal work resume 2173 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 17668 - answer by opening your turn with [!reply:17668]", "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", "meta": {"from": "journal"}}
{"content": "1 new message 17669 - answer by opening your turn with [!reply:17669]", "meta": {"from": "journal"}}
{"content": "helper 161, Olly Optionswift, reported in message 17670 \u2014 read it, then journal helper finish 161 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "1 new message 17671 - answer by opening your turn with [!reply:17671]", "meta": {"from": "journal"}}
{"content": "1 new message 17672 - answer by opening your turn with [!reply:17672]; message 17672 updated", "meta": {"from": "journal"}}
{"content": "helper 163, Wendell Waitwise, reported in message 17674 \u2014 read it, then journal helper finish 163 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "1 new message 17675 - answer by opening your turn with [!reply:17675]", "meta": {"from": "journal"}}
{"content": "1 new message 17676 - answer by opening your turn with [!reply:17676]", "meta": {"from": "journal"}}
{"content": "1 new message 17677 - answer by opening your turn with [!reply:17677]", "meta": {"from": "journal"}}
{"content": "1 new message 17678 - answer by opening your turn with [!reply:17678]", "meta": {"from": "journal"}}
{"content": "1 new message 17679 - answer by opening your turn with [!reply:17679]", "meta": {"from": "journal"}}
{"content": "message 17679 updated", "meta": {"from": "journal"}}
{"content": "1 new message 17680 - answer by opening your turn with [!reply:17680]", "meta": {"from": "journal"}}
{"content": "1 new message 17681 - answer by opening your turn with [!reply:17681]", "meta": {"from": "journal"}}
{"content": "your last message ran its paragraphs together \u2014 a blank line between parts is what makes a message readable: one thought to a paragraph", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "journal 2.254.8 is out, this project runs 2.254.4 - run journal upgrade to install it", "meta": {"from": "journal"}}
{"content": "1 new message 17684 - answer by opening your turn with [!reply:17684]", "meta": {"from": "journal"}}
{"content": "1 new message 17685 - answer by opening your turn with [!reply:17685]", "meta": {"from": "journal"}}
{"content": "helper 160, Petra Projectwide, reported in message 17686 \u2014 read it, then journal helper finish 160 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "the user set the work mode to solo \u2014 From now on you do all the work yourself: no subagents and no helpers.; 1 new message 17689 - answer by opening your turn with [!reply:17689]", "meta": {"from": "journal"}}
{"content": "1 new message 17690 - answer by opening your turn with [!reply:17690]", "meta": {"from": "journal"}}
{"content": "helper 165, Linnea Lockwood, reported in message 17691 \u2014 read it, then journal helper finish 165 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "1 new message 17693 - answer by opening your turn with [!reply:17693]", "meta": {"from": "journal"}}
{"content": "the todo tag does this in one step \u2014 [!todo=\"the title\"] files it with the turn as its brief; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "1 new message 17695 - answer by opening your turn with [!reply:17695]", "meta": {"from": "journal"}}
{"content": "helper 157, Nell Notewell, reported in message 17697 \u2014 read it, then journal helper finish 157 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "work 2175 in hand \u2014 Waiting on The footmen at work - Nell's push, Nadine\u2026 \u2014 if this is not what you are doing, end it or park it and start the work you are in", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2176 stands still while todo 3189 is ready \u2014 if work 2176 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3189. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "journal 2.254.8 is out, this project runs 2.254.4 - run journal upgrade to install it", "meta": {"from": "journal"}}
{"content": "commit 0152912f1 closed to-do 3193 and ended work 2176 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "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 2 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 2 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.", "meta": {"from": "journal"}}
{"content": "commit 724a5ec8c closed to-do 3189 and ended work 2177 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "rule 56 \u2014 Helpers are for work that writes; subagents read, research and design \u2014 The user, message 13464: there must be a clear distinction. A subagent can be dispatched for anything read-only: research, review, design. A helper is for actual work that writes, best in its own worktree when the work is separate. Dieter designing in Claude Design should have been a subagent, not a helper.", "meta": {"from": "journal"}}
{"content": "1 new message 17701 - answer by opening your turn with [!reply:17701]; message 17701 updated", "meta": {"from": "journal"}}
{"content": "1 new message 17703 - answer by opening your turn with [!reply:17703]; message 17703 updated", "meta": {"from": "journal"}}
{"content": "1 new message 17704 - answer by opening your turn with [!reply:17704]", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 2 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 2 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.", "meta": {"from": "journal"}}
{"content": "your command ran 33s 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": "work 2178 in hand \u2014 Waiting on The suite on the model and journal-list fixes\u2026 \u2014 if this is not what you are doing, end it or park it and start the work you are in", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat; answer message 17704 before you write anything \u2014 answer by opening your turn with [!reply:17704]. a reply, a reaction, or journal message processed <n>; Code Commandments \u2014 before you wrap up \u2014 you've changed 3 judged files since th\u2026 \u2014 Code Commandments \u2014 before you wrap up: 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.", "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.; rule 61 \u2014 Features wait as pull requests until approved; only hotfixes merge\u2026 \u2014 Message 17118 (2026-10-06), after the overnight refactor merged as 2.252.0: start new work in a new branch, do not merge, write the pull request. Every pull request or new feature is parked until the user approves it. Hotfixes can be merged into main immediately (by a dispatched agent in a worktree of main, rule 60).", "meta": {"from": "journal"}}
{"content": "helper 161, Olly Optionswift, reported in message 17709 \u2014 read it, then journal helper finish 161 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "commit a3ba4a571 closed to-do 3194 and ended work 2179 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "rule 57 \u2014 Never merge the overnight refactor into main before its pull request\u2026 \u2014 Messages 15005, 15006, 15109, 15110 (2026-10-04): all refactor work goes on branch overnight-refactor and reaches the user as one pull request, which they read in the morning; nothing of it is merged into main until they say so. Hotfixes the user explicitly asks for go to main at once and are merged into the branch.", "meta": {"from": "journal"}}
{"content": "rule 59 \u2014 Every viewer heading and label says plainly what it is about \u2014 The user, messages 16499, 16839, 16844, 16989, 16992 and 16993 (2026-10-06), after 'Where the words count', 'Watch for the words in', 'This project', 'This browser' and 'Stop the journal' as tab names: viewer text reads like Linear, GitHub or Vercel. A place (page, tab, group, sidebar item) is a short noun: Settings, Project, Browser, Services, Updates, Plugins; never 'This project' or a phrase. A button is a verb for what happens: Stop, Install, Copy link, Pause the plan. A heading names what the reader looks at, and its options finish its sentence: 'Trigger when' / 'A word is written'. Plain literal words: no metaphor or whimsy ('kettle on, waiting'), no app speaking as I, none of the journal's internal words (row, hook, nudge, engine, slate). One word for one thing everywhere, sentence case, as short as it can be while clear. Applies to designers' prototypes, helpers' builds, the viewer's JavaScript lists, feature details, and shipped sequence and trigger titles alike.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 the files changed since the last check (`launch.py`, `envir\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`launch.py`, `environments.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-dict-bag at /Users/jessegall/projects/agent-journal/.claude/worktrees/main-project-settings/src/controllers/environments.py:107 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `commandments info <sin>` if a rule is not one you recognise. This check reads a file at a time, so it is not the whole picture \u2014 `judge` still is.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you wrap up \u2014 you've changed 4 judged files since th\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 4 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.", "meta": {"from": "journal"}}
{"content": "1 new message 17714 - answer by opening your turn with [!reply:17714]", "meta": {"from": "journal"}}
{"content": "work 2181 in hand \u2014 An environment made without a kind silently becomes a main\u2026 \u2014 if this is not what you are doing, end it or park it and start the work you are in; the todo tag does this in one step \u2014 [!todo=\"the title\"] files it with the turn as its brief; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "1 new message 17716 - answer by opening your turn with [!reply:17716]", "meta": {"from": "journal"}}
{"content": "message 17716 file Screenshot 2026-10-07 at 13.43.16.png needs tags \u2014 inspect the attachment, then journal message tag 17716 \"Screenshot 2026-10-07 at 13.43.16.png\" \"<a few words describing what it shows>\"; message 17716 updated", "meta": {"from": "journal"}}
{"content": "helper 158, Nadine Nudgeworth, reported in message 17717 \u2014 read it, then journal helper finish 158 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "1 new message 17718 - answer by opening your turn with [!reply:17718]", "meta": {"from": "journal"}}
{"content": "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": "commit 40d86f737 closed to-do 3201 and ended work 2182 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "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 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": "answer message 17714 before you write anything \u2014 answer by opening your turn with [!reply:17714]. a reply, a reaction, or journal message processed <n>; auto mode is on and work 2183 stands still while todo 3196 is ready \u2014 if work 2183 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3196. Stop only when nothing ready is left.; fact 20 \u2014 A slim supervisor holds the agent and a worker reloads on every build \u2014 Since 2.118.0 (2026-09-23). src/supervisor.py is standard library only and never reloads: journal claude hands its process over to it (os.execv), and it owns the pty and the agent process, relays the terminal, writes the printed and screen captures, listens on the typist socket, restarts the agent in the same session from a relaunch command written to its runtime folder while a restart is pending, and stops it with escalation while draining the pty (an agent cannot finish exiting on macOS while its output is unread). It starts the worker (src/worker.py, which runs runner/worker.py; engine/worker.py stays as an alias for supervisors started before 2.201) and starts it again whenever it exits: RELOAD on a new build, RELAUNCH to restart the agent, STOP to end, HEAL or a quick crash to roll back a build through journal heal. The worker holds everything else: seating the session, the start-up confirm typed through the typist, services, viewer, update check, check-in, and the one-time relaunch of sessions launched before agents/terminal.py LAUNCH. agents/terminal.py holds only journal-side helpers. The server (serve.py) still runs the engines and re-execs itself on a .py change. When the agent exits, the supervisor runs journal ended, which puts set-aside hooks back and stops the server when no session is left.", "meta": {"from": "journal"}}
{"content": "1 new message 17720 - answer by opening your turn with [!reply:17720]", "meta": {"from": "journal"}}
{"content": "1 new message 17721 - answer by opening your turn with [!reply:17721]", "meta": {"from": "journal"}}
{"content": "message 17721 updated", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 2 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 2 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.", "meta": {"from": "journal"}}
{"content": "answer message 17721 before you write anything \u2014 answer by opening your turn with [!reply:17721]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "1 new message 17725 - answer by opening your turn with [!reply:17725]", "meta": {"from": "journal"}}
{"content": "1 new message 17727 - answer by opening your turn with [!reply:17727]", "meta": {"from": "journal"}}
{"content": "1 new message 17728 - answer by opening your turn with [!reply:17728]", "meta": {"from": "journal"}}
{"content": "1 new message 17729 - answer by opening your turn with [!reply:17729]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat; your last message ran its paragraphs together \u2014 a blank line between parts is what makes a message readable: one thought to a paragraph", "meta": {"from": "journal"}}
{"content": "1 new message 17730 - answer by opening your turn with [!reply:17730]", "meta": {"from": "journal"}}
{"content": "1 new message 17731 - answer by opening your turn with [!reply:17731]", "meta": {"from": "journal"}}
{"content": "1 new message 17732 - answer by opening your turn with [!reply:17732]", "meta": {"from": "journal"}}
{"content": "1 new message 17733 - answer by opening your turn with [!reply:17733]; message 17733 updated", "meta": {"from": "journal"}}
{"content": "1 new message 17734 - answer by opening your turn with [!reply:17734]; message 17734 updated", "meta": {"from": "journal"}}
{"content": "helper 162, Quentin Quickhush, reported in message 17735 \u2014 read it, then journal helper finish 162 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "1 new message 17736 - answer by opening your turn with [!reply:17736]; message 17736 updated", "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.", "meta": {"from": "journal"}}
{"content": "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 55 \u2014 Always dispatch Codex helpers on gpt-6-sol \u2014 The user's word, message 13431: switch the codex agents to GPT-6-Sol and make it their default. ~/.codex/config.toml names it as the default model too.; rule 56 \u2014 Helpers are for work that writes; subagents read, research and design \u2014 The user, message 13464: there must be a clear distinction. A subagent can be dispatched for anything read-only: research, review, design. A helper is for actual work that writes, best in its own worktree when the work is separate. Dieter designing in Claude Design should have been a subagent, not a helper.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2185 stands still while todo 3199 is ready \u2014 if work 2185 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3199. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "work 2187 in hand \u2014 Release 2.254.12, then merge the waiting pull requests \u2014 if this is not what you are doing, end it or park it and start the work you are in", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you wrap up \u2014 you've changed 15 judged files since t\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 15 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.", "meta": {"from": "journal"}}
{"content": "The whole suite on 2.254.12, which now carries every fix from this afternoon\u2026", "meta": {"from": "journal"}}
{"content": "1 new message 17746 - answer by opening your turn with [!reply:17746]", "meta": {"from": "journal"}}
{"content": "1 new message 17747 - answer by opening your turn with [!reply:17747]", "meta": {"from": "journal"}}
{"content": "1 new message 17750 - answer by opening your turn with [!reply:17750]", "meta": {"from": "journal"}}
{"content": "your command ran 31s 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 whole suite on 2.254.12 came back - Run the whole suite on 2.254.12 again\u2026", "meta": {"from": "journal"}}
{"content": "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.", "meta": {"from": "journal"}}
{"content": "helper 159, Tobias Tipwell, reported in message 17752 \u2014 read it, then journal helper finish 159 once its work is taken or dropped", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "rule 51 \u2014 Every finished feature is committed, pushed and released with a new\u2026 \u2014 Message 9207 (2026-09-24): when a new feature is ready, commit, push and publish a new tag. This is the user's standing word for releasing, so rule 44's only-when-the-user-says is met by it for finished features; fixes in between wait for the next feature or a patch the user asks for.", "meta": {"from": "journal"}}
{"content": "rule 42 \u2014 Every user-facing text passes the formatters before it leaves the\u2026 \u2014 Not only a brief. A title, an abstract, an outcome and every section body are read by a person, so each goes through the same formatters on its way to the viewer \u2014 chat turns, activity items, to-do rows, inspector pages, docs alike. One field formatted out of five is not a rule, it is an accident, and it is how a raw tag ended up in the activity list after the tags feature had been stripping them for weeks. When a new field carries words a person reads, it joins the list in the same place.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 the files changed since the last check (`AgentStartButton.v\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`AgentStartButton.vue`, `client.js`, `HubPage.vue`, `test.py`, `controller.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 plain-viewer-text at /Users/jessegall/projects/agent-journal/.claude/worktrees/main-integrate/src/web/src/pages/HubPage.vue:99 \u00b7 LOAD the skill `commandments-plain-viewer-text` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `commandments info <sin>` if a rule is not one you recognise. This check reads a file at a time, so it is not the whole picture \u2014 `judge` still is.; command plugin raise is slower than its budget \u2014 230ms last (154ms of it working, 7ms collecting garbage), against a budget of 50ms. Seen 2 times.", "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 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.; 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 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.; rule 62 \u2014 The voice profile shapes only the agent's chat speech, never code or\u2026 \u2014 The user, message 17620 (2026-10-07): the profile (butler, homie, coach, colleague) must not leak into the code the agent writes or into user-facing text of any application it works on: names, labels, comments, commit messages, docs and briefs written into a project use plain words (helper, subagent). Speaking in the chat in the profile's voice is fine.", "meta": {"from": "journal"}}
{"content": "work 2187 in hand \u2014 Release 2.254.12, then merge the waiting pull requests \u2014 if this is not what you are doing, end it or park it and start the work you are in; 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": "answer message 17750 before you write anything \u2014 answer by opening your turn with [!reply:17750]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "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 - \"Still waiting\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "The whole suite on 2.255.0, which holds every merged pull request came back\u2026", "meta": {"from": "journal"}}
{"content": "fact 23 \u2014 Every upgrade brings system sequences and their triggers in line\u2026 \u2014 install.py runs ship_sequences after the migrations on each upgrade, so features/sequences/shipped.py is the whole source: change its wording and the next upgrade updates every journal, no migration needed. Shipped rows carry system=True and are read-only for everyone but SYSTEM (controllers/base.py _shipped).", "meta": {"from": "journal"}}
{"content": "your command ran 33s 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": "Code Commandments \u2014 before you wrap up \u2014 you've changed 1 judged file since the\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 1 judged file 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.", "meta": {"from": "journal"}}
{"content": "The phone's agent browser scenario, run alone after the merge came back - Run\u2026", "meta": {"from": "journal"}}
{"content": "1 new message 17762 - answer by opening your turn with [!reply:17762]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 405ms last (278ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 165 times.", "meta": {"from": "journal"}}
{"content": "law L3 \u2014 Read narrowly - grep for the line, sed a range, head the file; never\u2026 \u2014 Everything a tool returns stays in the context for good and is paid for on every turn after it. Search before you read, read the range you need, and cap output with grep, head or tail. Read a whole file only when you need all of it.", "meta": {"from": "journal"}}
{"content": "the reply tag does this in one step \u2014 [!reply:N] makes the turn itself the reply; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "rule 43 \u2014 A request or hook over its budget is fixed before the next release \u2014 Comment 1151 on this rule. When the faults feature reports a request, a hook or a command slower than its budget, file it as a to-do at once. It does not jump ahead of the work in hand, but no version is published while one is still open: profile it, fix it, and verify the new time before the release goes out. The budget is 50ms, because everything runs locally against files.", "meta": {"from": "journal"}}
{"content": "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": "auto mode is on and work 2187 stands still while todo 3204 is ready \u2014 if work 2187 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3204. Stop only when nothing ready is left.; rule 59 \u2014 Every viewer heading and label says plainly what it is about \u2014 The user, messages 16499, 16839, 16844, 16989, 16992 and 16993 (2026-10-06), after 'Where the words count', 'Watch for the words in', 'This project', 'This browser' and 'Stop the journal' as tab names: viewer text reads like Linear, GitHub or Vercel. A place (page, tab, group, sidebar item) is a short noun: Settings, Project, Browser, Services, Updates, Plugins; never 'This project' or a phrase. A button is a verb for what happens: Stop, Install, Copy link, Pause the plan. A heading names what the reader looks at, and its options finish its sentence: 'Trigger when' / 'A word is written'. Plain literal words: no metaphor or whimsy ('kettle on, waiting'), no app speaking as I, none of the journal's internal words (row, hook, nudge, engine, slate). One word for one thing everywhere, sentence case, as short as it can be while clear. Applies to designers' prototypes, helpers' builds, the viewer's JavaScript lists, feature details, and shipped sequence and trigger titles alike.", "meta": {"from": "journal"}}
{"content": "work 2186, Two environments changing different project settings at once can\u2026 \u2014 it was parked because: Waits until pull request 17 is merged. journal work resume 2186 picks it up again.; 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.; rule 57 \u2014 Never merge the overnight refactor into main before its pull request\u2026 \u2014 Messages 15005, 15006, 15109, 15110 (2026-10-04): all refactor work goes on branch overnight-refactor and reaches the user as one pull request, which they read in the morning; nothing of it is merged into main until they say so. Hotfixes the user explicitly asks for go to main at once and are merged into the branch.; rule 61 \u2014 Features wait as pull requests until approved; only hotfixes merge\u2026 \u2014 Message 17118 (2026-10-06), after the overnight refactor merged as 2.252.0: start new work in a new branch, do not merge, write the pull request. Every pull request or new feature is parked until the user approves it. Hotfixes can be merged into main immediately (by a dispatched agent in a worktree of main, rule 60).", "meta": {"from": "journal"}}
{"content": "The phone agent scenario rerun on the merged 2.255.0 came back - Rerun the\u2026", "meta": {"from": "journal"}}
{"content": "rule 54 \u2014 Settings and feature switches are read at boot and on change, never\u2026 \u2014 The user, message 13349: the application boots, determines every feature and setting once, and re-evaluates only when something changes, such as a setting or a plugin. Never lazy-load settings.", "meta": {"from": "journal"}}
{"content": "The phone profile scenario rerun, to see which button it waited on came back\u2026", "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 phone profile scenario, once more came back - Run the phone agent scenario\u2026", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 143ms last (52ms of it working), against a budget of 50ms. Seen 166 times.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2187 stands still while todo 3206 is ready \u2014 if work 2187 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3206. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "work 2186, Two environments changing different project settings at once can\u2026 \u2014 it was parked because: Waits until pull request 17 is merged. journal work resume 2186 picks it up again.", "meta": {"from": "journal"}}
{"content": "The phone profile scenario's captured failure came back - Capture the whole\u2026", "meta": {"from": "journal"}}
{"content": "context 96% full, decide \u2014 a fact is what a later reader would get wrong without, a rule binds every environment, or nothing \"<why>\"", "meta": {"from": "journal"}}
{"content": "the user changed how you talk to them \u2014 From now on: HOW THE USER WANTS YOU TO TALK, in their own words: Talk like a good butler: polite, calm and to the point. Use my title and name when you answer one of my messages, and now and then otherwise, never in every message. Keep a dry sense of humour. Now and then, when it fits, tip your hat with a \ud83c\udfa9 reaction when I call you sir, or put a funny reaction on my message; never on every one. When I send a meme, make a joke or scold you, answer with one dry, witty line in character, then put the matter right. Address me as \"Sir Jesse\". In the chat, and only there, call your helpers footmen, each a footman. In code, in text written into a project, in commit messages, in docs and in briefs to other agents, always write helper and subagent.; request GET /api/main-integrate/dashboard is slower than its budget \u2014 93ms last (82ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "1 new message 1 - answer by opening your turn with [!reply:1]", "meta": {"from": "journal"}}
{"content": "answer message 1 before you write anything \u2014 answer by opening your turn with [!reply:1]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "command message waiting is slower than its budget \u2014 73ms last (67ms of it working, 6ms collecting garbage), against a budget of 50ms. Seen 1 time.; 1 new message 17772 - answer by opening your turn with [!reply:17772]", "meta": {"from": "journal"}}
{"content": "fact 20 \u2014 A slim supervisor holds the agent and a worker reloads on every build \u2014 Since 2.118.0 (2026-09-23). src/supervisor.py is standard library only and never reloads: journal claude hands its process over to it (os.execv), and it owns the pty and the agent process, relays the terminal, writes the printed and screen captures, listens on the typist socket, restarts the agent in the same session from a relaunch command written to its runtime folder while a restart is pending, and stops it with escalation while draining the pty (an agent cannot finish exiting on macOS while its output is unread). It starts the worker (src/worker.py, which runs runner/worker.py; engine/worker.py stays as an alias for supervisors started before 2.201) and starts it again whenever it exits: RELOAD on a new build, RELAUNCH to restart the agent, STOP to end, HEAL or a quick crash to roll back a build through journal heal. The worker holds everything else: seating the session, the start-up confirm typed through the typist, services, viewer, update check, check-in, and the one-time relaunch of sessions launched before agents/terminal.py LAUNCH. agents/terminal.py holds only journal-side helpers. The server (serve.py) still runs the engines and re-execs itself on a .py change. When the agent exits, the supervisor runs journal ended, which puts set-aside hooks back and stops the server when no session is left.; rule 60 \u2014 A hotfix is done by a dispatched agent in a worktree of main \u2014 Message 16836 (2026-10-06): the orchestrator cut a worktree under .claude/worktrees for a Codex hotfix, its session moved to a new environment and the user's messages stopped reaching it. The user: when working on a branch and a hotfix comes in, create a worktree of main and dispatch an agent to do that work. The orchestrator stays on its branch and in its environment, and never cds into another checkout.", "meta": {"from": "journal"}}
{"content": "your command ran 33s 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": "1 new message 17775 - answer by opening your turn with [!reply:17775]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "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.; 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.; rule 50 \u2014 Everything the user does is doable in the viewer \u2014 Message 6710 (2026-09-23): the user never uses the CLI, only the UI; everything should be doable from the viewer. The journal commands are for agents; any action meant for the user (making boards, confirming, accepting, hosting, watching an agent) needs its place in the viewer.; to-do 3210 came from message 17775? \u2014 link it: journal message process 17775 \"<their words>\" todo:3210", "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 27 \u2014 Running src/journal.py against the live .journal root starts a\u2026 \u2014 Seen 2026-10-01: with VERSION bumped in the tree, src/journal.py --root .journal saw the live server as another build and started a new one on a new port (8431, 8432), and the user's tabs kept losing connection. Run source builds against a throwaway or demo root (~/projects/demo-crumb/.journal), never the live one, until the release is installed.; fact 28 \u2014 The designer agent type exists, so design work goes to a subagent \u2014 Since 2026-10-01 .claude/agents/designer.md (Dieter, Opus, Claude Design tools, read-only on the repository) is an agent type; rule 56 says design is a subagent's job, never a helper's.; fact 30 \u2014 The tunler server refuses TLS for any subdomain without a tunnel \u2014 Seen 2026-10-04 in the server's docker logs (ssh root@tunler.jessegall.nl, container tunler): 'TLS handshake error ... host \"journal-probe.tunler.jessegall.nl\" not allowed'. A made-up subdomain never answers even when the server is healthy; probe https://tunler.jessegall.nl/ for the server itself. Root SSH to the server works.; 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.; rule 58 \u2014 A design runs three critique rounds, then is built on a branch \u2014 Messages 17276 and 17281 (2026-10-06): the norm is a three-round cycle. Round by round, the designer designs (or revises), separate critic agents review the design through their lenses (the critic agent type, .claude/agents/critic.md: read-only, with a browser; one per lens, such as first-time, native, words and parity), and the designer adjusts it to their findings; three rounds in all. The three rounds stand in for the user's approval of the design: the user does not approve it. After the third round the design is built on a branch of its own, which ends in a pull request that waits for the user's approval (rule 61). Replaces message 15725's prototype approval.; rule 63 \u2014 A small design is drawn once and the user approves it, with no\u2026 \u2014 The user, messages 17628 and 17629 (2026-10-07), about the tooltip and waiting-status designs: 'This design round doesn't really need multiple rounds... I just want the designer agent to design it, and I will approve it.' Rule 58's three critique rounds are for large designs such as the phone app; a small one (a tooltip, a status word, one control) is drawn once by the designer, the link goes to the user, and it is built once the user approves it.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 6 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 6 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 39 \u2014 Use only registered exclamation response tags \u2014 A tag like [!reply:12] runs a command, and only the tags in the tags.runs setting are registered. An invented tag does nothing and shows as raw text in the chat. Use the registered ones (reply, log, end, todo, fact, rule) and nothing else.", "meta": {"from": "journal"}}
{"content": "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.; rule 56 \u2014 Helpers are for work that writes; subagents read, research and design \u2014 The user, message 13464: there must be a clear distinction. A subagent can be dispatched for anything read-only: research, review, design. A helper is for actual work that writes, best in its own worktree when the work is separate. Dieter designing in Claude Design should have been a subagent, not a helper.", "meta": {"from": "journal"}}
{"content": "your command ran 31s 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": "helper 164, Hilda Hangfinder, stopped running before it reported \u2014 its agent is gone, so journal helper say cannot reach it. Dispatch the job again, or journal helper finish 164 and do the job yourself", "meta": {"from": "journal"}}
{"content": "work 2186, Two environments changing different project settings at once can\u2026 \u2014 it was parked because: Waits until pull request 17 is merged. journal work resume 2186 picks it up again.; 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 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 55 \u2014 Always dispatch Codex helpers on gpt-6-sol \u2014 The user's word, message 13431: switch the codex agents to GPT-6-Sol and make it their default. ~/.codex/config.toml names it as the default model too.", "meta": {"from": "journal"}}
{"content": "your message 17782 names 161, 3209 without saying what they are \u2014 put the type before each number, like message 1712 or to-do 644, so the chat links it: journal message edit 17782 \"<the text>\"; todo 3209 next", "meta": {"from": "journal"}}
{"content": "1 new message 17783 - answer by opening your turn with [!reply:17783]", "meta": {"from": "journal"}}
{"content": "request GET /api/pages is slower than its budget \u2014 587ms last (57ms of it working), against a budget of 50ms. Seen 8 times.", "meta": {"from": "journal"}}
{"content": "rule 51 \u2014 Every finished feature is committed, pushed and released with a new\u2026 \u2014 Message 9207 (2026-09-24): when a new feature is ready, commit, push and publish a new tag. This is the user's standing word for releasing, so rule 44's only-when-the-user-says is met by it for finished features; fixes in between wait for the next feature or a patch the user asks for.; 1 new message 17785 - answer by opening your turn with [!reply:17785]", "meta": {"from": "journal"}}
{"content": "message 17785 file IMG_1201.png needs tags \u2014 inspect the attachment, then journal message tag 17785 \"IMG_1201.png\" \"<a few words describing what it shows>\"; message 17785 updated", "meta": {"from": "journal"}}
{"content": "1 new message 17787 - answer by opening your turn with [!reply:17787]", "meta": {"from": "journal"}}
{"content": "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 60 \u2014 A hotfix is done by a dispatched agent in a worktree of main \u2014 Message 16836 (2026-10-06): the orchestrator cut a worktree under .claude/worktrees for a Codex hotfix, its session moved to a new environment and the user's messages stopped reaching it. The user: when working on a branch and a hotfix comes in, create a worktree of main and dispatch an agent to do that work. The orchestrator stays on its branch and in its environment, and never cds into another checkout.", "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": "1 new message 17795 - answer by opening your turn with [!reply:17795]", "meta": {"from": "journal"}}
{"content": "1 new message 17796 - answer by opening your turn with [!reply:17796]", "meta": {"from": "journal"}}
{"content": "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": "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.", "meta": {"from": "journal"}}
{"content": "work 2186, Two environments changing different project settings at once can\u2026 \u2014 it was parked because: Waits until pull request 17 is merged. journal work resume 2186 picks it up again.; commit 9ce15fcb5 closed to-do 3209 and ended work 2189 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "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": "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; your message 17797 names 3208 without saying what they are \u2014 put the type before each number, like message 1712 or to-do 644, so the chat links it: journal message edit 17797 \"<the text>\"; todo 3211 next; fact 18 \u2014 cProfile inflates the slow-request profiles about tenfold \u2014 The faults feature writes a profile when a request passes its budget, and the profile is taken with cProfile, which adds per-call overhead. On 2026-09-22 /api/summary profiled at 58ms with 48ms inside Resource.fork's deep copy; with the profiler off the same call ran in 2 to 7ms. Read the profile for where the time goes in relative terms, then time the call with curl before changing anything.", "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": "todo 3211 next", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat; your chat talked about the journal's workings - \"Still waiting\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead; 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.; 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": "your chat talked about the journal's workings - \"Still waiting\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 269ms last (256ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 168 times.", "meta": {"from": "journal"}}
{"content": "question 210 completed", "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.", "meta": {"from": "journal"}}
{"content": "1 new message 17804 - answer by opening your turn with [!reply:17804]", "meta": {"from": "journal"}}
{"content": "fact 20 \u2014 A slim supervisor holds the agent and a worker reloads on every build \u2014 Since 2.118.0 (2026-09-23). src/supervisor.py is standard library only and never reloads: journal claude hands its process over to it (os.execv), and it owns the pty and the agent process, relays the terminal, writes the printed and screen captures, listens on the typist socket, restarts the agent in the same session from a relaunch command written to its runtime folder while a restart is pending, and stops it with escalation while draining the pty (an agent cannot finish exiting on macOS while its output is unread). It starts the worker (src/worker.py, which runs runner/worker.py; engine/worker.py stays as an alias for supervisors started before 2.201) and starts it again whenever it exits: RELOAD on a new build, RELAUNCH to restart the agent, STOP to end, HEAL or a quick crash to roll back a build through journal heal. The worker holds everything else: seating the session, the start-up confirm typed through the typist, services, viewer, update check, check-in, and the one-time relaunch of sessions launched before agents/terminal.py LAUNCH. agents/terminal.py holds only journal-side helpers. The server (serve.py) still runs the engines and re-execs itself on a .py change. When the agent exits, the supervisor runs journal ended, which puts set-aside hooks back and stops the server when no session is left.", "meta": {"from": "journal"}}
{"content": "rule 42 \u2014 Every user-facing text passes the formatters before it leaves the\u2026 \u2014 Not only a brief. A title, an abstract, an outcome and every section body are read by a person, so each goes through the same formatters on its way to the viewer \u2014 chat turns, activity items, to-do rows, inspector pages, docs alike. One field formatted out of five is not a rule, it is an accident, and it is how a raw tag ended up in the activity list after the tags feature had been stripping them for weeks. When a new field carries words a person reads, it joins the list in the same place.", "meta": {"from": "journal"}}
{"content": "rule 51 \u2014 Every finished feature is committed, pushed and released with a new\u2026 \u2014 Message 9207 (2026-09-24): when a new feature is ready, commit, push and publish a new tag. This is the user's standing word for releasing, so rule 44's only-when-the-user-says is met by it for finished features; fixes in between wait for the next feature or a patch the user asks for.", "meta": {"from": "journal"}}
{"content": "question 211 completed", "meta": {"from": "journal"}}
{"content": "the whole suite on 2.255.2 came back - Bump to 2.255.2 with its changelog and\u2026", "meta": {"from": "journal"}}
{"content": "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 39 \u2014 Use only registered exclamation response tags \u2014 A tag like [!reply:12] runs a command, and only the tags in the tags.runs setting are registered. An invented tag does nothing and shows as raw text in the chat. Use the registered ones (reply, log, end, todo, fact, rule) and nothing else.", "meta": {"from": "journal"}}
{"content": "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.; fact 27 \u2014 Running src/journal.py against the live .journal root starts a\u2026 \u2014 Seen 2026-10-01: with VERSION bumped in the tree, src/journal.py --root .journal saw the live server as another build and started a new one on a new port (8431, 8432), and the user's tabs kept losing connection. Run source builds against a throwaway or demo root (~/projects/demo-crumb/.journal), never the live one, until the release is installed.", "meta": {"from": "journal"}}
{"content": "rule 52 \u2014 A chat mark for something the user did sits on the user's side \u2014 Message 10960 (2026-09-25): marks for the user's own actions, such as answering a question, are right-aligned like the user's messages. A mark is put there by giving its card side=user.; comment 3036 file IMG_1201.png needs tags \u2014 inspect the attachment, then journal comment tag 3036 \"IMG_1201.png\" \"<a few words describing what it shows>\"", "meta": {"from": "journal"}}
{"content": "1 new message 17806 - answer by opening your turn with [!reply:17806]", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"I've replied\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead; fact 18 \u2014 cProfile inflates the slow-request profiles about tenfold \u2014 The faults feature writes a profile when a request passes its budget, and the profile is taken with cProfile, which adds per-call overhead. On 2026-09-22 /api/summary profiled at 58ms with 48ms inside Resource.fork's deep copy; with the profiler off the same call ran in 2 to 7ms. Read the profile for where the time goes in relative terms, then time the call with curl before changing anything.; rule 43 \u2014 A request or hook over its budget is fixed before the next release \u2014 Comment 1151 on this rule. When the faults feature reports a request, a hook or a command slower than its budget, file it as a to-do at once. It does not jump ahead of the work in hand, but no version is published while one is still open: profile it, fix it, and verify the new time before the release goes out. The budget is 50ms, because everything runs locally against files.", "meta": {"from": "journal"}}
{"content": "1 new message 17808 - answer by opening your turn with [!reply:17808]", "meta": {"from": "journal"}}
{"content": "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": "rule 57 \u2014 Never merge the overnight refactor into main before its pull request\u2026 \u2014 Messages 15005, 15006, 15109, 15110 (2026-10-04): all refactor work goes on branch overnight-refactor and reaches the user as one pull request, which they read in the morning; nothing of it is merged into main until they say so. Hotfixes the user explicitly asks for go to main at once and are merged into the branch.; rule 61 \u2014 Features wait as pull requests until approved; only hotfixes merge\u2026 \u2014 Message 17118 (2026-10-06), after the overnight refactor merged as 2.252.0: start new work in a new branch, do not merge, write the pull request. Every pull request or new feature is parked until the user approves it. Hotfixes can be merged into main immediately (by a dispatched agent in a worktree of main, rule 60).", "meta": {"from": "journal"}}
{"content": "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.; 1 new message 17809 - answer by opening your turn with [!reply:17809]", "meta": {"from": "journal"}}
{"content": "work 2186, Two environments changing different project settings at once can\u2026 \u2014 it was parked because: Waits until pull request 17 is merged. journal work resume 2186 picks it up again.; 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.", "meta": {"from": "journal"}}
{"content": "1 new message 17810 - answer by opening your turn with [!reply:17810]", "meta": {"from": "journal"}}
{"content": "law L3 \u2014 Read narrowly - grep for the line, sed a range, head the file; never\u2026 \u2014 Everything a tool returns stays in the context for good and is paid for on every turn after it. Search before you read, read the range you need, and cap output with grep, head or tail. Read a whole file only when you need all of it.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 1 of 6 - Add the report\u2019s section headings \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:84. Lead with the answer in the report's brief, then put every part you plan on the report before writing any of them: journal report section 84 \"<part>\" \"Being written.\" for each, in order: the evidence, what was already sound, what remains uncertain. Then journal sequence next 10 --about report:84.", "meta": {"from": "journal"}}
{"content": "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 Related work goes back to the helper or subagent that already worked\u2026 \u2014 A helper or subagent that drew a design, wrote the code or ran the research keeps what it learned. When new work changes its work, is related to it or touches the same code, send it there with a message (SendMessage, journal helper say) 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.; rule 56 \u2014 Helpers are for work that writes; subagents read, research and design \u2014 The user, message 13464: there must be a clear distinction. A subagent can be dispatched for anything read-only: research, review, design. A helper is for actual work that writes, best in its own worktree when the work is separate. Dieter designing in Claude Design should have been a subagent, not a helper.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 2 of 6 - Write the report\u2019s sections \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:84. Write the parts one at a time and in order with journal report section 84 \"<part>\" \"<body>\"; the user sees each one appear where you are. Then journal sequence next 10 --about report:84.; fact 23 \u2014 Every upgrade brings system sequences and their triggers in line\u2026 \u2014 install.py runs ship_sequences after the migrations on each upgrade, so features/sequences/shipped.py is the whole source: change its wording and the next upgrade updates every journal, no migration needed. Shipped rows carry system=True and are read-only for everyone but SYSTEM (controllers/base.py _shipped).; 1 new message 17811 - answer by opening your turn with [!reply:17811]", "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": "sequence 10, Writing a report, step 3 of 6 - Add the document or report to a\u2026 \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:84. If a collection the user keeps fits what you wrote, add it: journal collection add <collection n> report:84. Look with journal collection all first. When none fits but other documents or reports on the same subject sit in no collection, make one named for the subject with journal collection create \"<subject>\", add this and them, and say so in one line. A row with nothing related gets no collection of its own. Then journal sequence next 10 --about report:84.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 4 of 6 - Link the items behind the\u2026 \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:84. Link the rows it answers or was built on, such as the to-dos, plans, documents, reports or messages it is about, with journal report link 84 \"<row>\" for each. Leave out rows it only mentions in passing. Then journal sequence next 10 --about report:84.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 5 of 6 - Offer the user a next step \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:84. If it asks the user to decide or approve something, give it buttons: journal report update 84 --set buttons='[{\"label\": \"Accept this proposal\", \"say\": \"I accept this proposal\", \"choice\": \"answer\"}, {\"label\": \"Change it first\", \"say\": \"I want changes first\", \"choice\": \"answer\"}]'. A button with say sends those words to you as the user's message; one naming a type, n and action runs that command. Buttons of one decision share a choice, so the others go once one is pressed. Skip this when nothing waits on the user. Then journal sequence next 10 --about report:84.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 6 of 6 - Tell the user in the chat \u2014 Finishing this sequence comes before anything else you do; everything else waits until it is finished or abandoned. Take it up first with journal sequence follow 10 --about report:84. Say in one or two plain lines what it concludes, then its reference on a line of its own, like doc 41 or report 98, never in backticks. Finish with journal sequence next 10 --about report:84.", "meta": {"from": "journal"}}
{"content": "1 new message 17813 - answer by opening your turn with [!reply:17813]; report 84 updated", "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.", "meta": {"from": "journal"}}
{"content": "1 new message 17814 - answer by opening your turn with [!reply:17814]", "meta": {"from": "journal"}}
{"content": "1 new message 17815 - answer by opening your turn with [!reply:17815]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "work 2186, Two environments changing different project settings at once can\u2026 \u2014 it was parked because: Waits until pull request 17 is merged. journal work resume 2186 picks it up again.; 1 new message 17816 - answer by opening your turn with [!reply:17816]", "meta": {"from": "journal"}}
{"content": "1 new message 17817 - answer by opening your turn with [!reply:17817]", "meta": {"from": "journal"}}
{"content": "rule 54 \u2014 Settings and feature switches are read at boot and on change, never\u2026 \u2014 The user, message 13349: the application boots, determines every feature and setting once, and re-evaluates only when something changes, such as a setting or a plugin. Never lazy-load settings.; Is rule 64 a ruling for the whole project? \u2014 rule 64, \"A finished feature is merged into main without waiting for approval\", binds every environment of the project. Keep it only if it is a ruling for all of them, worded as one (\"Always ...\", \"Never ...\"). If it is about this environment or its current work, strike it with journal rule strike 64 --how \"<why>\" and file it here as a fact or a reminder instead.", "meta": {"from": "journal"}}
{"content": "rule 60 \u2014 A hotfix is done by a dispatched agent in a worktree of main \u2014 Message 16836 (2026-10-06): the orchestrator cut a worktree under .claude/worktrees for a Codex hotfix, its session moved to a new environment and the user's messages stopped reaching it. The user: when working on a branch and a hotfix comes in, create a worktree of main and dispatch an agent to do that work. The orchestrator stays on its branch and in its environment, and never cds into another checkout.; rule 64 \u2014 A finished feature is merged into main without waiting for approval \u2014 The user, message 17815 (2026-10-07): 'make sure that no pull requests are lingering on the repository. You may merge them into main... You are allowed to merge everything into main once the feature is completed.' This replaces rule 61's wait for approval: a feature still goes on its own branch, and once it is complete, tested and its whole suite passes, it is merged into main and released, and no pull request is left open.", "meta": {"from": "journal"}}
{"content": "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.", "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": "1 new message 17819 - answer by opening your turn with [!reply:17819]", "meta": {"from": "journal"}}
{"content": "rule 27 \u2014 Name a declaration with the word a reader already knows \u2014 An attribute, a variable or a field gets the ordinary programming word for what it holds, not an evocative one. was, heard and alone were poetry; aliases, notify_actions and urgent_actions are what they are. The test: could a reader who has never seen this codebase guess what it holds from the name alone? Prose belongs in the help text and the abstract, where it is read as prose. This does not license abbreviations \u2014 a plain word in full, not a short one.; 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 55 \u2014 Always dispatch Codex helpers on gpt-6-sol \u2014 The user's word, message 13431: switch the codex agents to GPT-6-Sol and make it their default. ~/.codex/config.toml names it as the default model too.; rule 62 \u2014 The voice profile shapes only the agent's chat speech, never code or\u2026 \u2014 The user, message 17620 (2026-10-07): the profile (butler, homie, coach, colleague) must not leak into the code the agent writes or into user-facing text of any application it works on: names, labels, comments, commit messages, docs and briefs written into a project use plain words (helper, subagent). Speaking in the chat in the profile's voice is fine.", "meta": {"from": "journal"}}
{"content": "rule 50 \u2014 Everything the user does is doable in the viewer \u2014 Message 6710 (2026-09-23): the user never uses the CLI, only the UI; everything should be doable from the viewer. The journal commands are for agents; any action meant for the user (making boards, confirming, accepting, hosting, watching an agent) needs its place in the viewer.", "meta": {"from": "journal"}}
{"content": "rule 42 \u2014 Every user-facing text passes the formatters before it leaves the\u2026 \u2014 Not only a brief. A title, an abstract, an outcome and every section body are read by a person, so each goes through the same formatters on its way to the viewer \u2014 chat turns, activity items, to-do rows, inspector pages, docs alike. One field formatted out of five is not a rule, it is an accident, and it is how a raw tag ended up in the activity list after the tags feature had been stripping them for weeks. When a new field carries words a person reads, it joins the list in the same place.; rule 59 \u2014 Every viewer heading and label says plainly what it is about \u2014 The user, messages 16499, 16839, 16844, 16989, 16992 and 16993 (2026-10-06), after 'Where the words count', 'Watch for the words in', 'This project', 'This browser' and 'Stop the journal' as tab names: viewer text reads like Linear, GitHub or Vercel. A place (page, tab, group, sidebar item) is a short noun: Settings, Project, Browser, Services, Updates, Plugins; never 'This project' or a phrase. A button is a verb for what happens: Stop, Install, Copy link, Pause the plan. A heading names what the reader looks at, and its options finish its sentence: 'Trigger when' / 'A word is written'. Plain literal words: no metaphor or whimsy ('kettle on, waiting'), no app speaking as I, none of the journal's internal words (row, hook, nudge, engine, slate). One word for one thing everywhere, sentence case, as short as it can be while clear. Applies to designers' prototypes, helpers' builds, the viewer's JavaScript lists, feature details, and shipped sequence and trigger titles alike.", "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 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": "1 new message 17821 - answer by opening your turn with [!reply:17821]", "meta": {"from": "journal"}}
{"content": "rule 51 \u2014 Every finished feature is committed, pushed and released with a new\u2026 \u2014 Message 9207 (2026-09-24): when a new feature is ready, commit, push and publish a new tag. This is the user's standing word for releasing, so rule 44's only-when-the-user-says is met by it for finished features; fixes in between wait for the next feature or a patch the user asks for.", "meta": {"from": "journal"}}
{"content": "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.; 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": "work 2192 in hand \u2014 After a compaction the agent reads the last 50 messages \u2014 if this is not what you are doing, end it or park it and start the work you are in", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 2192 stands still while todo 3211 is ready \u2014 if work 2192 waits on the user, decide it yourself when you can; otherwise put the question on its row with journal todo ask, end or park the work, and start todo 3211. Stop only when nothing ready is left.; 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.", "meta": {"from": "journal"}}
{"content": "the await tag does this in one step \u2014 [!await] makes the rest of the turn what you wait for; [!await on=(\"<id>\", \"helper:<n>\")] waits on those; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "The whole suite on 2.256.0, before the read-after-compaction hold goes to\u2026", "meta": {"from": "journal"}}
{"content": "1 new message 17827 - answer by opening your turn with [!reply:17827]", "meta": {"from": "journal"}}
{"content": "Waiting on the rerun of the update and boot tests; if they pass, 2.256.0 goes\u2026", "meta": {"from": "journal"}}
{"content": "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 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.; rule 39 \u2014 Use only registered exclamation response tags \u2014 A tag like [!reply:12] runs a command, and only the tags in the tags.runs setting are registered. An invented tag does nothing and shows as raw text in the chat. Use the registered ones (reply, log, end, todo, fact, rule) and nothing else.; 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": "1 new message 17828 - answer by opening your turn with [!reply:17828]", "meta": {"from": "journal"}}
{"content": "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.; fact 27 \u2014 Running src/journal.py against the live .journal root starts a\u2026 \u2014 Seen 2026-10-01: with VERSION bumped in the tree, src/journal.py --root .journal saw the live server as another build and started a new one on a new port (8431, 8432), and the user's tabs kept losing connection. Run source builds against a throwaway or demo root (~/projects/demo-crumb/.journal), never the live one, until the release is installed.", "meta": {"from": "journal"}}
{"content": "work 2186, Two environments changing different project settings at once can\u2026 \u2014 it was parked because: Waits until pull request 17 is merged. journal work resume 2186 picks it up again.", "meta": {"from": "journal"}}
{"content": "the phone's address did not answer 2 times, so its tunnel was restarted", "meta": {"from": "journal"}}
{"content": "check 31 failed - subprocess.CalledProcessError - Command '['gh', 'api', 'user', \u2014 journal check show 31 says why; fix it, then journal check run 31", "meta": {"from": "journal"}}
{"content": "fact 30 \u2014 The tunler server refuses TLS for any subdomain without a tunnel \u2014 Seen 2026-10-04 in the server's docker logs (ssh root@tunler.jessegall.nl, container tunler): 'TLS handshake error ... host \"journal-probe.tunler.jessegall.nl\" not allowed'. A made-up subdomain never answers even when the server is healthy; probe https://tunler.jessegall.nl/ for the server itself. Root SSH to the server works.", "meta": {"from": "journal"}}
{"content": "your command ran 31s 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": "think up what the user might ask for on board 12, Orchestrator \u2014 read its goal and cards (journal board show 12), then write 3 to 5 short things the user might ask for next, each one chip of at most 60 characters, in the user's words: journal board ideas 12 \"<idea>\" \"<idea>\" \"<idea>\". They replace the board's ideas under New work.; think up what the user might ask for on board 13, New work trials \u2014 read its goal and cards (journal board show 13), then write 3 to 5 short things the user might ask for next, each one chip of at most 60 characters, in the user's words: journal board ideas 13 \"<idea>\" \"<idea>\" \"<idea>\". They replace the board's ideas under New work.", "meta": {"from": "journal"}}
{"content": "1 new message 17833 - answer by opening your turn with [!reply:17833]", "meta": {"from": "journal"}}
{"content": "the reply tag does this in one step \u2014 [!reply:N] makes the turn itself the reply; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "law L3 \u2014 Read narrowly - grep for the line, sed a range, head the file; never\u2026 \u2014 Everything a tool returns stays in the context for good and is paid for on every turn after it. Search before you read, read the range you need, and cap output with grep, head or tail. Read a whole file only when you need all of it.", "meta": {"from": "journal"}}
{"content": "rule 52 \u2014 A chat mark for something the user did sits on the user's side \u2014 Message 10960 (2026-09-25): marks for the user's own actions, such as answering a question, are right-aligned like the user's messages. A mark is put there by giving its card side=user.", "meta": {"from": "journal"}}
{"content": "1 new message 17835 - answer by opening your turn with [!reply:17835]", "meta": {"from": "journal"}}
{"content": "1 new message 17838 - answer by opening your turn with [!reply:17838]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 302ms last (231ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 169 times.", "meta": {"from": "journal"}}
{"content": "rule 60 \u2014 A hotfix is done by a dispatched agent in a worktree of main \u2014 Message 16836 (2026-10-06): the orchestrator cut a worktree under .claude/worktrees for a Codex hotfix, its session moved to a new environment and the user's messages stopped reaching it. The user: when working on a branch and a hotfix comes in, create a worktree of main and dispatch an agent to do that work. The orchestrator stays on its branch and in its environment, and never cds into another checkout.", "meta": {"from": "journal"}}
{"content": "1 new message 17839 - answer by opening your turn with [!reply:17839]", "meta": {"from": "journal"}}
{"content": "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": "1 new message 17840 - answer by opening your turn with [!reply:17840]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 a turn that only handles a journal line needs no words: act on it, or say once in the chat what you wait on, then carry on; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "1 new message 17841 - answer by opening your turn with [!reply:17841]", "meta": {"from": "journal"}}
{"content": "1 new message 17842 - answer by opening your turn with [!reply:17842]", "meta": {"from": "journal"}}
{"content": "1 new message 17843 - answer by opening your turn with [!reply:17843]", "meta": {"from": "journal"}}
{"content": "1 new message 17844 - answer by opening your turn with [!reply:17844]", "meta": {"from": "journal"}}
{"content": "1 new message 17845 - answer by opening your turn with [!reply:17845]", "meta": {"from": "journal"}}
{"content": "the reply tag does this in one step \u2014 [!reply:N] makes the turn itself the reply; it runs only when it opens the last text of your turn; fact 23 \u2014 Every upgrade brings system sequences and their triggers in line\u2026 \u2014 install.py runs ship_sequences after the migrations on each upgrade, so features/sequences/shipped.py is the whole source: change its wording and the next upgrade updates every journal, no migration needed. Shipped rows carry system=True and are read-only for everyone but SYSTEM (controllers/base.py _shipped).; rule 54 \u2014 Settings and feature switches are read at boot and on change, never\u2026 \u2014 The user, message 13349: the application boots, determines every feature and setting once, and re-evaluates only when something changes, such as a setting or a plugin. Never lazy-load settings.", "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 Related work goes back to the helper or subagent that already worked\u2026 \u2014 A helper or subagent that drew a design, wrote the code or ran the research keeps what it learned. When new work changes its work, is related to it or touches the same code, send it there with a message (SendMessage, journal helper say) 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.; rule 56 \u2014 Helpers are for work that writes; subagents read, research and design \u2014 The user, message 13464: there must be a clear distinction. A subagent can be dispatched for anything read-only: research, review, design. A helper is for actual work that writes, best in its own worktree when the work is separate. Dieter designing in Claude Design should have been a subagent, not a helper.", "meta": {"from": "journal"}}
{"content": "question 212 completed", "meta": {"from": "journal"}}
{"content": "message 17846 file Screenshot 2026-10-07 at 19.07.41.png needs tags \u2014 inspect the attachment, then journal message tag 17846 \"Screenshot 2026-10-07 at 19.07.41.png\" \"<a few words describing what it shows>\"; 1 new message 17846 - answer by opening your turn with [!reply:17846]; message 17846 updated", "meta": {"from": "journal"}}
{"content": "rule 55 \u2014 Always dispatch Codex helpers on gpt-6-sol \u2014 The user's word, message 13431: switch the codex agents to GPT-6-Sol and make it their default. ~/.codex/config.toml names it as the default model too.; rule 64 \u2014 A finished feature is merged into main without waiting for approval \u2014 The user, message 17815 (2026-10-07): 'make sure that no pull requests are lingering on the repository. You may merge them into main... You are allowed to merge everything into main once the feature is completed.' This replaces rule 61's wait for approval: a feature still goes on its own branch, and once it is complete, tested and its whole suite passes, it is merged into main and released, and no pull request is left open.", "meta": {"from": "journal"}}
{"content": "1 new message 17847 - answer by opening your turn with [!reply:17847]", "meta": {"from": "journal"}}
{"content": "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.", "meta": {"from": "journal"}}
{"content": "message 17848 file Screenshot 2026-10-07 at 19.08.54.png needs tags \u2014 inspect the attachment, then journal message tag 17848 \"Screenshot 2026-10-07 at 19.08.54.png\" \"<a few words describing what it shows>\"; 1 new message 17848 - answer by opening your turn with [!reply:17848]; message 17848 updated", "meta": {"from": "journal"}}
{"content": "1 new message 17849 - answer by opening your turn with [!reply:17849]", "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.; 1 new message 17851 - answer by opening your turn with [!reply:17851]", "meta": {"from": "journal"}}
