{"content": "message 9000 file Screenshot 2026-09-24 at 14.03.38.png needs tags \u2014 inspect the attachment, then journal message tag 9000 \"Screenshot 2026-09-24 at 14.03.38.png\" \"<a few words describing what it shows>\"; 1 new message 9000 - answer by opening your turn with [!reply:9000]; message 9000 updated", "meta": {"from": "journal"}}
{"content": "1 new message 9001 - answer by opening your turn with [!reply:9001]", "meta": {"from": "journal"}}
{"content": "message 9018 file Screenshot 2026-09-24 at 14.33.34.png needs tags \u2014 inspect the attachment, then journal message tag 9018 \"Screenshot 2026-09-24 at 14.33.34.png\" \"<a few words describing what it shows>\"; 1 new message 9018 - answer by opening your turn with [!reply:9018]; message 9018 updated", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 44c704b49 closed to-do 1528 and ended work 1350 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "message 9022 file Screenshot 2026-09-24 at 14.36.59.png needs tags \u2014 inspect the attachment, then journal message tag 9022 \"Screenshot 2026-09-24 at 14.36.59.png\" \"<a few words describing what it shows>\"; 1 new message 9022 - answer by opening your turn with [!reply:9022]; message 9022 updated", "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": "commit fb27d8b91 closed to-do 1531, to-do 1532 and ended work 1352 \u2014 The rows and the work are done; take the next one.", "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": "your chat talked about the journal's workings - \"Nothing is waiting\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "1 new message 9040 - answer by opening your turn with [!reply:9040]", "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; work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 3bea7efe3 closed to-do 1533 and ended work 1353 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 65ms last (53ms of it working), against a budget of 50ms. Seen 833 times.", "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 9045 - answer by opening your turn with [!reply:9045]", "meta": {"from": "journal"}}
{"content": "message 9049 file Screenshot 2026-09-24 at 15.05.14.png needs tags \u2014 inspect the attachment, then journal message tag 9049 \"Screenshot 2026-09-24 at 15.05.14.png\" \"<a few words describing what it shows>\"; 1 new message 9049 - answer by opening your turn with [!reply:9049]; message 9049 updated", "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": "work 1354 in hand \u2014 A dump's next step can be the user's own direction \u2014 if this is not what you are doing, end it or park it and start the work you are in; 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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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.; request POST /api/run is slower than its budget \u2014 329ms last (66ms of it working), against a budget of 50ms. Seen 29 times.", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 954671366 closed to-do 1534 and ended work 1354 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "1 new message 9058 - answer by opening your turn with [!reply:9058]", "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": "request GET /api/main/dashboard is slower than its budget \u2014 118ms last (70ms of it working), against a budget of 50ms. Seen 836 times.", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; 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.; commit 09c1c0ab2 closed to-do 1535 and ended work 1355 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "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": "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.", "meta": {"from": "journal"}}
{"content": "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.", "meta": {"from": "journal"}}
{"content": "1 new message 9065 - answer by opening your turn with [!reply:9065]", "meta": {"from": "journal"}}
{"content": "1 new message 9068 - answer by opening your turn with [!reply:9068]", "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 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": "1 new message 9076 - answer by opening your turn with [!reply:9076]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 9079 - answer by opening your turn with [!reply:9079]", "meta": {"from": "journal"}}
{"content": "1 new message 9080 - answer by opening your turn with [!reply:9080]", "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": "commit 54622560a closed to-do 1540 and ended work 1357 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "message 9082 file Screenshot 2026-09-24 at 15.17.03.png needs tags \u2014 inspect the attachment, then journal message tag 9082 \"Screenshot 2026-09-24 at 15.17.03.png\" \"<a few words describing what it shows>\"; 1 new message 9082 - answer by opening your turn with [!reply:9082]; message 9082 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.; 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": "1 new message 9084 - answer by opening your turn with [!reply:9084]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 171ms last (160ms of it working), against a budget of 50ms. Seen 839 times.", "meta": {"from": "journal"}}
{"content": "rule 40 \u2014 A feature is named for what it is, never for its machinery \u2014 Messages 599, 600 and 703. A feature is a capability the user would name and would think of switching off. File tracking, a write gate, a phrase bank, a tree diff are services used inside a feature, not features of their own: they live in the feature they serve. Before adding a directory under features/, say what the user would call it; if the answer names a mechanism, it belongs inside something else. Report 16 holds the grouping this implies.", "meta": {"from": "journal"}}
{"content": "law 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": "answer message 9076 before you write anything \u2014 answer by opening your turn with [!reply:9076]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1358 stands still while todo 1542 is ready \u2014 if work 1358 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 1542. Stop only when nothing ready is left.; work 1358 is still open \u2014 end it or park it before you stop: journal work end 1358 --how \"<what landed>\", or journal work park 1358 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 345a2b94e closed to-do 1541, to-do 1542 and ended work 1358 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "1 new message 9090 - answer by opening your turn with [!reply:9090]", "meta": {"from": "journal"}}
{"content": "1 new message 9092 - answer by opening your turn with [!reply:9092]", "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": "1 new message 9094 - answer by opening your turn with [!reply:9094]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 152ms last (65ms of it working), against a budget of 50ms. Seen 844 times.; request GET /api/main/dashboard is slower than its budget \u2014 153ms last (62ms of it working), against a budget of 50ms. Seen 844 times.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1359 stands still while todo 1543 is ready \u2014 if work 1359 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 1543. Stop only when nothing ready is left.; work 1359 is still open \u2014 end it or park it before you stop: journal work end 1359 --how \"<what landed>\", or journal work park 1359 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9097 - answer by opening your turn with [!reply:9097]", "meta": {"from": "journal"}}
{"content": "1 new message 9100 - answer by opening your turn with [!reply:9100]", "meta": {"from": "journal"}}
{"content": "1 new message 9101 - answer by opening your turn with [!reply:9101]", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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.; 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.", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "todo 1547 next", "meta": {"from": "journal"}}
{"content": "1 new message 9105 - answer by opening your turn with [!reply:9105]", "meta": {"from": "journal"}}
{"content": "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": "work 1361 is still open \u2014 end it or park it before you stop: journal work end 1361 --how \"<what landed>\", or journal work park 1361 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9110 - answer by opening your turn with [!reply:9110]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1549 next", "meta": {"from": "journal"}}
{"content": "1 new message 9116 - answer by opening your turn with [!reply:9116]", "meta": {"from": "journal"}}
{"content": "todo 1536, New work can take a document and draft tickets from it, is\u2026 \u2014 journal todo start 1536 when it is next; todo 1537, A new board can be made from a document, is unblocked - todo 1538\u2026 \u2014 journal todo start 1537 when it is next; todo 1539, The dump is reimagined in the spirit of New work, is unblocked\u2026 \u2014 journal todo start 1539 when it is next; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1543, A designer refines New work's first dialog, is still blocked - is\u2026 \u2014 it is blocked because: Built and installed by Eileen; commits together with Ray's Documents redesign once he reports. If it is not any more, journal todo unblock 1543. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1545, A small scroll up in the chat no longer bounces, is still blocked\u2026 \u2014 it is blocked because: Done and built; commits with Eileen's New work dialog changes. If it is not any more, journal todo unblock 1545. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1546, The plan card waits for the scroll to settle before it changes, is\u2026 \u2014 it is blocked because: Done and built; commits with Eileen's New work dialog changes. If it is not any more, journal todo unblock 1546. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1549, A designer reimagines the Documents page, is still blocked - is it\u2026 \u2014 it is blocked because: Ray Eames, a designer agent, is redesigning the page; reviewed and committed when he reports. If it is not any more, journal todo unblock 1549. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "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": "1 new message 9118 - answer by opening your turn with [!reply:9118]", "meta": {"from": "journal"}}
{"content": "1 new message 9119 - answer by opening your turn with [!reply:9119]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 9121 - answer by opening your turn with [!reply:9121]", "meta": {"from": "journal"}}
{"content": "1 new message 9122 - answer by opening your turn with [!reply:9122]", "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.", "meta": {"from": "journal"}}
{"content": "1 new message 9124 - answer by opening your turn with [!reply:9124]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "meta": {"from": "journal"}}
{"content": "1 new message 9126 - answer by opening your turn with [!reply:9126]", "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 1363 stands still while todo 1536 is ready \u2014 if work 1363 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 1536. Stop only when nothing ready is left.; work 1363 is still open \u2014 end it or park it before you stop: journal work end 1363 --how \"<what landed>\", or journal work park 1363 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 74ms last (60ms of it working), against a budget of 50ms. Seen 850 times.", "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": "install.py names 2 files in the project \u2014 write the path so the chat can link it: install.py, src/install.py", "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": "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": "question 133 completed", "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": "question 134 completed", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"reading it\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "question 135 completed", "meta": {"from": "journal"}}
{"content": "1 new message 9141 - answer by opening your turn with [!reply:9141]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 174ms last (90ms of it working), against a budget of 50ms. Seen 852 times.", "meta": {"from": "journal"}}
{"content": "journal-auto-update, journal-facts, journal-reminders, journal-rules\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "question 137 completed", "meta": {"from": "journal"}}
{"content": "message 9145 file Screenshot 2026-09-24 at 15.40.25.png needs tags \u2014 inspect the attachment, then journal message tag 9145 \"Screenshot 2026-09-24 at 15.40.25.png\" \"<a few words describing what it shows>\"; 1 new message 9145 - answer by opening your turn with [!reply:9145]; message 9145 updated", "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": "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": "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "work 1362 is still open \u2014 end it or park it before you stop: journal work end 1362 --how \"<what landed>\", or journal work park 1362 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9150 - answer by opening your turn with [!reply:9150]", "meta": {"from": "journal"}}
{"content": "1 new message 9151 - answer by opening your turn with [!reply:9151]", "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.", "meta": {"from": "journal"}}
{"content": "1 new message 9153 - answer by opening your turn with [!reply:9153]", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; journal-auto-update, journal-facts, journal-pinned-links, journal-reminders\u2026 \u2014 load one again when you next need it; only the every-start skills are held for; commit 260854220 closed to-do 1543, to-do 1544, to-do 1545, to-do 1546, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "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": "message 9154 file Screenshot 2026-09-24 at 15.45.06.png needs tags \u2014 inspect the attachment, then journal message tag 9154 \"Screenshot 2026-09-24 at 15.45.06.png\" \"<a few words describing what it shows>\"; 1 new message 9154 - answer by opening your turn with [!reply:9154]; message 9154 updated", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 235ms last (147ms of it working), against a budget of 50ms. Seen 856 times.", "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": "todo 1537 next; commit 20b9ce1cd closed to-do 1562, to-do 1563 and ended work 1365 \u2014 The rows and the work are done; take the next one.", "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": "1 new message 9158 - answer by opening your turn with [!reply:9158]", "meta": {"from": "journal"}}
{"content": "plan 15 updated", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1366 stands still while todo 1539 is ready \u2014 if work 1366 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 1539. Stop only when nothing ready is left.; work 1366 is still open, with nothing logged \u2014 journal work log 1366 \"<what was decided or done, and why>\" \u2014 then journal work end 1366 --how \"<what landed>\", or journal work park 1366 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "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": "1 new message 9161 - answer by opening your turn with [!reply:9161]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 199ms last (150ms of it working), against a budget of 50ms. Seen 858 times.", "meta": {"from": "journal"}}
{"content": "answer message 9161 before you write anything \u2014 answer by opening your turn with [!reply:9161]. a reply, a reaction, or journal message processed <n>", "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 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": "1 new message 9164 - answer by opening your turn with [!reply:9164]", "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.; rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "sequence 4, Working a card from the board, step 1 of 5 - Understand the request \u2014 Goal: find out which feature they want to build. This turn never drafts. Read the context before you write anything: the board's name and brief (journal board show <board n>) and the cards already on it (journal ticket board <board n>). They usually say what the feature is about: on a board called Shared Journal, \"I want to share\" is about a shareable journal. Offer the three features their words most likely mean on this board, most likely first, each clearly different from the others, with a short line under each saying what it would give them: journal board ask <board n> \"Which <kind of feature> do you mean?\" --abstract \"<one plain line on why you read it so>\" --set options='[{\"title\": \"<feature>\", \"text\": \"<what it gives them>\"}, ...]'. When their words already name one feature, the first option is their request as written and the other two are its nearest larger and smaller versions. When their words cannot be read, the question is \"I couldn't read that. Which of these?\". The abstract never names the board or its cards. Never offer filler such as Yes / No, and never an open question without options when you can guess. The question is your whole turn: do not reply to their message. When it is answered: journal sequence next <this sequence> --about <ref>. When it is done: journal sequence next 4 --about message:9166; 1 new message 9166 - answer by opening your turn with [!reply:9166]; message 9166 requested", "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 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": "you ran the same check 3 times in a row - journal todo create \"Several viewer\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.", "meta": {"from": "journal"}}
{"content": "fact 22 \u2014 A shipped sequence change reaches existing journals only through a\u2026 \u2014 features/sequences/shipped.py ship() runs from migrations (m0022, m0028, m0029), and each migration runs once per record. Since 2026-09-24 ship() brings a system sequence's brief, start and steps in step with the code, but only when a migration calls it: a wording change needs a new mNNNN file that re-exports m0022's run.", "meta": {"from": "journal"}}
{"content": "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.", "meta": {"from": "journal"}}
{"content": "you ran the same check 3 times in a row - journal board ask 12 \"I couldn't\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.", "meta": {"from": "journal"}}
{"content": "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": "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": "question 139 completed; sequence 4 updated", "meta": {"from": "journal"}}
{"content": "message 9170 file Screenshot 2026-09-24 at 15.52.43.png needs tags \u2014 inspect the attachment, then journal message tag 9170 \"Screenshot 2026-09-24 at 15.52.43.png\" \"<a few words describing what it shows>\"; 1 new message 9170 - answer by opening your turn with [!reply:9170]; message 9170 updated", "meta": {"from": "journal"}}
{"content": "1 new message 9171 - answer by opening your turn with [!reply:9171]", "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": "request GET /api/main/files is slower than its budget \u2014 83ms last (50ms of it working), against a budget of 50ms. Seen 1 time.", "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": "request GET /api/main/dashboard is slower than its budget \u2014 147ms last (134ms of it working), against a budget of 50ms. Seen 859 times.", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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 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": "1 new message 9175 - answer by opening your turn with [!reply:9175]", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "1 new message 9178 - answer by opening your turn with [!reply:9178]", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 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 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": "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": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "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": "request GET /api/main/dashboard is slower than its budget \u2014 255ms last (69ms of it working), against a budget of 50ms. Seen 862 times.", "meta": {"from": "journal"}}
{"content": "work 1366 in hand \u2014 A new board can be made from a document \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": "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": "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": "1 new message 9186 - answer by opening your turn with [!reply:9186]", "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": "question 140 completed", "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 4, Working a card from the board, step 1 of 5 - Understand the request \u2014 Goal: find out which feature they want to build. This turn never drafts. Read the context before you write anything: the board's name and brief (journal board show <board n>) and the cards already on it (journal ticket board <board n>). They usually say what the feature is about: on a board called Shared Journal, \"I want to share\" is about a shareable journal. Offer the three features their words most likely mean on this board, most likely first, each clearly different from the others, with a short line under each saying what it would give them: journal board ask <board n> \"Which <kind of feature> do you mean?\" --abstract \"<one plain line on why you read it so>\" --set options='[{\"title\": \"<feature>\", \"text\": \"<what it gives them>\"}, ...]'. When their words already name one feature, the first option is their request as written and the other two are its nearest larger and smaller versions. When their words cannot be read, the question is \"I couldn't read that. Which of these?\". The abstract never names the board or its cards. Never offer filler such as Yes / No, and never an open question without options when you can guess. The question is your whole turn: do not reply to their message. When it is answered: journal sequence next <this sequence> --about <ref>. When it is done: journal sequence next 4 --about message:9188; 1 new message 9188 - answer by opening your turn with [!reply:9188]; message 9188 requested", "meta": {"from": "journal"}}
{"content": "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 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": "question 141 completed", "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": "question 142 completed", "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": "fact 22 \u2014 A shipped sequence change reaches existing journals only through a\u2026 \u2014 features/sequences/shipped.py ship() runs from migrations (m0022, m0028, m0029), and each migration runs once per record. Since 2026-09-24 ship() brings a system sequence's brief, start and steps in step with the code, but only when a migration calls it: a wording change needs a new mNNNN file that re-exports m0022's run.; sequence 4, Working a card from the board, step 2 of 5 - Narrow it down \u2014 Goal: shape the feature they picked until you can write its tickets. Always take this round, even when the first answer felt clear. Ask one question about the part of the feature that most decides the tickets, in terms of what they would see or do, never how it is built, with three options that each carry an example: journal board ask <board n> \"<the question>\" --abstract \"<their pick, settled, in a few words, like A shared journal, then.>\" --set options='[{\"title\": \"<direction>\", \"text\": \"For example, <what they would get>\"}, ...]'. The question is your whole turn. When it is answered: journal sequence next <this sequence> --about <ref>. When it is done: journal sequence next 4 --about message:9188", "meta": {"from": "journal"}}
{"content": "question 143 completed; sequence 4 updated", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 288ms last (248ms of it working), against a budget of 50ms. Seen 863 times.", "meta": {"from": "journal"}}
{"content": "message 9192 file Screenshot 2026-09-24 at 16.04.09.png needs tags \u2014 inspect the attachment, then journal message tag 9192 \"Screenshot 2026-09-24 at 16.04.09.png\" \"<a few words describing what it shows>\"; 1 new message 9192 - answer by opening your turn with [!reply:9192]; message 9192 updated", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit a6bc9b92a closed to-do 1537, to-do 1564, to-do 1565, to-do 1567, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "answer message 9192 before you write anything \u2014 answer by opening your turn with [!reply:9192]. a reply, a reaction, or journal message processed <n>; 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.", "meta": {"from": "journal"}}
{"content": "1 new message 9194 - answer by opening your turn with [!reply:9194]", "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": "request GET /api/main/files is slower than its budget \u2014 94ms last (66ms of it working), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1368 stands still while todo 1539 is ready \u2014 if work 1368 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 1539. Stop only when nothing ready is left.; work 1368 is still open \u2014 end it or park it before you stop: journal work end 1368 --how \"<what landed>\", or journal work park 1368 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "auto mode is on and work 1368 stands still while todo 1539 is ready \u2014 if work 1368 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 1539. Stop only when nothing ready is left.; work 1368 is still open \u2014 end it or park it before you stop: journal work end 1368 --how \"<what landed>\", or journal work park 1368 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9199 - answer by opening your turn with [!reply:9199]", "meta": {"from": "journal"}}
{"content": "message 9199 deleted", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1368 stands still while todo 1539 is ready \u2014 if work 1368 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 1539. Stop only when nothing ready is left.; work 1368 is still open \u2014 end it or park it before you stop: journal work end 1368 --how \"<what landed>\", or journal work park 1368 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9202 - answer by opening your turn with [!reply:9202]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit fd7a6b907 closed to-do 1571 and ended work 1368 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 300ms last (111ms of it working), against a budget of 50ms. Seen 868 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.", "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": "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 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 9207 - answer by opening your turn with [!reply:9207]", "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.; 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": "Is rule 51 a ruling for the whole project? \u2014 rule 51, \"Every finished feature is committed, pushed and released with a new version tag\", 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 51 --how \"<why>\" and file it here as a fact or a reminder instead.", "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.; rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1370 stands still while todo 1539 is ready \u2014 if work 1370 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 1539. Stop only when nothing ready is left.; work 1370 is still open \u2014 end it or park it before you stop: journal work end 1370 --how \"<what landed>\", or journal work park 1370 \"<why it waits>\"", "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": "todo 1568 next; 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": "request GET /api/main/dashboard is slower than its budget \u2014 121ms last (80ms of it working), against a budget of 50ms. Seen 871 times.", "meta": {"from": "journal"}}
{"content": "message 9217 file Screenshot 2026-09-24 at 16.14.56.png needs tags \u2014 inspect the attachment, then journal message tag 9217 \"Screenshot 2026-09-24 at 16.14.56.png\" \"<a few words describing what it shows>\"; 1 new message 9217 - answer by opening your turn with [!reply:9217]; message 9217 updated", "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.", "meta": {"from": "journal"}}
{"content": "journal-dumps changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "1 new message 9219 - answer by opening your turn with [!reply:9219]", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 111ms last (68ms of it working), against a budget of 50ms. Seen 30 times.", "meta": {"from": "journal"}}
{"content": "fact 22 \u2014 A shipped sequence change reaches existing journals only through a\u2026 \u2014 features/sequences/shipped.py ship() runs from migrations (m0022, m0028, m0029), and each migration runs once per record. Since 2026-09-24 ship() brings a system sequence's brief, start and steps in step with the code, but only when a migration calls it: a wording change needs a new mNNNN file that re-exports m0022's run.", "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.; rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 228ms last (113ms of it working), against a budget of 50ms. Seen 877 times.", "meta": {"from": "journal"}}
{"content": "message 9228 file Screenshot 2026-09-24 at 16.18.49.png needs tags \u2014 inspect the attachment, then journal message tag 9228 \"Screenshot 2026-09-24 at 16.18.49.png\" \"<a few words describing what it shows>\"; 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.; 1 new message 9228 - answer by opening your turn with [!reply:9228]; message 9228 updated", "meta": {"from": "journal"}}
{"content": "work 1371 in hand \u2014 New work can take a document and draft tickets from it \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": "1 new message 9241 - answer by opening your turn with [!reply:9241]", "meta": {"from": "journal"}}
{"content": "message 9242 file Screenshot 2026-09-24 at 16.26.07.png needs tags \u2014 inspect the attachment, then journal message tag 9242 \"Screenshot 2026-09-24 at 16.26.07.png\" \"<a few words describing what it shows>\"; 1 new message 9242 - answer by opening your turn with [!reply:9242]; message 9242 updated", "meta": {"from": "journal"}}
{"content": "1 new message 9271 - answer by opening your turn with [!reply:9271]", "meta": {"from": "journal"}}
{"content": "todo 1576 next", "meta": {"from": "journal"}}
{"content": "message 9275 file Screenshot 2026-09-24 at 16.35.46.png needs tags \u2014 inspect the attachment, then journal message tag 9275 \"Screenshot 2026-09-24 at 16.35.46.png\" \"<a few words describing what it shows>\"; 1 new message 9275 - answer by opening your turn with [!reply:9275]; message 9275 updated", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1568, Asking for an update or a TLDR runs a sequence that writes an\u2026 \u2014 it is blocked because: Otl is redrawing the update report in the viewer's quiet style (message 9194); built once the user has seen it. If it is not any more, journal todo unblock 1568. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1576, One composer button, Dump files when empty and Send once there is\u2026 \u2014 it is blocked because: Starts once 2.124.0 is committed, so Charlotte's edits stay out of the release commit. If it is not any more, journal todo unblock 1576. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1575, The agent picks drafts for the user when asked, is unblocked - todo\u2026 \u2014 journal todo start 1575 when it is next; request GET /api/main/dashboard is slower than its budget \u2014 744ms last (105ms of it working), against a budget of 50ms. Seen 890 times.; commit 705e90a09 closed to-do 1539, to-do 1566, to-do 1536, to-do 1570, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "todo 1576 next", "meta": {"from": "journal"}}
{"content": "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": "todo 1576 next", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "meta": {"from": "journal"}}
{"content": "1 new message 9282 - answer by opening your turn with [!reply:9282]", "meta": {"from": "journal"}}
{"content": "fact 22 \u2014 A shipped sequence change reaches existing journals only through a\u2026 \u2014 features/sequences/shipped.py ship() runs from migrations (m0022, m0028, m0029), and each migration runs once per record. Since 2026-09-24 ship() brings a system sequence's brief, start and steps in step with the code, but only when a migration calls it: a wording change needs a new mNNNN file that re-exports m0022's run.", "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": "waiting: 2 unread sequences 6, 7", "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 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": "1 new message 9289 - answer by opening your turn with [!reply:9289]", "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": "question 144 completed", "meta": {"from": "journal"}}
{"content": "message 9293 file Screenshot 2026-09-24 at 14.36.59.png needs tags \u2014 inspect the attachment, then journal message tag 9293 \"Screenshot 2026-09-24 at 14.36.59.png\" \"<a few words describing what it shows>\"; request GET /api/main/dashboard is slower than its budget \u2014 114ms last (68ms of it working), against a budget of 50ms. Seen 892 times.; request GET /api/main/dashboard is slower than its budget \u2014 110ms last (61ms of it working), against a budget of 50ms. Seen 892 times.; 1 new message 9293 - answer by opening your turn with [!reply:9293]; message 9293 updated", "meta": {"from": "journal"}}
{"content": "question 145 completed", "meta": {"from": "journal"}}
{"content": "work 1378 is still open, with nothing logged \u2014 journal work log 1378 \"<what was decided or done, and why>\" \u2014 then journal work end 1378 --how \"<what landed>\", or journal work park 1378 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1378 is still open \u2014 end it or park it before you stop: journal work end 1378 --how \"<what landed>\", or journal work park 1378 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "message 9313 file Screenshot 2026-09-24 at 16.48.12.png needs tags \u2014 inspect the attachment, then journal message tag 9313 \"Screenshot 2026-09-24 at 16.48.12.png\" \"<a few words describing what it shows>\"; 1 new message 9313 - answer by opening your turn with [!reply:9313]; message 9313 updated", "meta": {"from": "journal"}}
{"content": "todo 1582 next", "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": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1568, Asking for an update or a TLDR runs a sequence that writes an\u2026 \u2014 it is blocked because: Otl, the designer subagent, is building it in this tree; I review and release it when he reports. If it is not any more, journal todo unblock 1568. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "work 1379 is still open, with nothing logged \u2014 journal work log 1379 \"<what was decided or done, and why>\" \u2014 then journal work end 1379 --how \"<what landed>\", or journal work park 1379 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 242ms last (184ms of it working), against a budget of 50ms. Seen 901 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9320 - answer by opening your turn with [!reply:9320]", "meta": {"from": "journal"}}
{"content": "1 new message 9322 - answer by opening your turn with [!reply:9322]", "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": "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "meta": {"from": "journal"}}
{"content": "journal-dumps, journal-triggers changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "fact 22 \u2014 A shipped sequence change reaches existing journals only through a\u2026 \u2014 features/sequences/shipped.py ship() runs from migrations (m0022, m0028, m0029), and each migration runs once per record. Since 2026-09-24 ship() brings a system sequence's brief, start and steps in step with the code, but only when a migration calls it: a wording change needs a new mNNNN file that re-exports m0022's run.", "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.; 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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; message 9326 file image.png needs tags \u2014 inspect the attachment, then journal message tag 9326 \"image.png\" \"<a few words describing what it shows>\"; 1 new message 9326 - answer by opening your turn with [!reply:9326]; message 9326 updated", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "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 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": "1 new message 9329 - answer by opening your turn with [!reply:9329]", "meta": {"from": "journal"}}
{"content": "1 new message 9330 - answer by opening your turn with [!reply:9330]", "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": "answer message 9330 before you write anything \u2014 answer by opening your turn with [!reply:9330]. a reply, a reaction, or journal message processed <n>; work 1380 in hand \u2014 Sequence steps name the real board, and system sequences\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": "request GET /api/main/dashboard is slower than its budget \u2014 179ms last (72ms of it working), against a budget of 50ms. Seen 903 times.; request GET /api/main/dashboard is slower than its budget \u2014 188ms last (71ms of it working), against a budget of 50ms. Seen 903 times.", "meta": {"from": "journal"}}
{"content": "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.; rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "message 9334 file image.png needs tags \u2014 inspect the attachment, then journal message tag 9334 \"image.png\" \"<a few words describing what it shows>\"; 1 new message 9334 - answer by opening your turn with [!reply:9334]; message 9334 updated", "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": "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": "journal-dumps, journal-pinned-links, journal-triggers changed since you loaded\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; 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": "todo 1583 next", "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": "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": "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.; report 43 cites nothing it was built on \u2014 you read report:42 just now: journal report link 43 \"<ref>\" for whichever it came from", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1382 stands still while todo 1585 is ready \u2014 if work 1382 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 1585. Stop only when nothing ready is left.; work 1382 is still open \u2014 end it or park it before you stop: journal work end 1382 --how \"<what landed>\", or journal work park 1382 \"<why it waits>\"; request GET /api/main/dashboard is slower than its budget \u2014 118ms last (55ms of it working), against a budget of 50ms. Seen 904 times.; request GET /api/main/dashboard is slower than its budget \u2014 112ms last (51ms of it working), against a budget of 50ms. Seen 904 times.", "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": "commit 04e466d80 closed to-do 1568 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1384 stands still while todo 1586 is ready \u2014 if work 1384 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 1586. Stop only when nothing ready is left.; work 1384 is still open, with nothing logged \u2014 journal work log 1384 \"<what was decided or done, and why>\" \u2014 then journal work end 1384 --how \"<what landed>\", or journal work park 1384 \"<why it waits>\"", "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": "commit 99c45166f closed to-do 1586 and ended work 1385 \u2014 The rows and the work are done; take the next one.", "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 8, Writing an update, step 1 of 3 - See what changed \u2014 journal report changes lists what happened since the user last opened an update, under need, done, doing, plans, commits and also. Read any row you do not remember before you sum it up. Then journal sequence next 8 --about trigger:3. When it is done: journal sequence next 8 --about trigger:3; 1 new message 9353 - answer by opening your turn with [!reply:9353]", "meta": {"from": "journal"}}
{"content": "sequence 8, Writing an update, step 2 of 3 - Write the update \u2014 journal report recap \"<one or two plain sentences: what got done, what is under way, what waits on the user>\" writes the report with those rows in that order. Give every row under need and doing a short note of what it waits on or what is being done now: journal report note <report n> trigger:3 \"<line>\". Add a row the list missed with journal report item <report n> <section> trigger:3 \"<title>\", and take out one that is only noise with journal report drop <report n> trigger:3. Then journal sequence next 8 --about trigger:3. When it is done: journal sequence next 8 --about trigger:3", "meta": {"from": "journal"}}
{"content": "report 44 cites nothing it was built on \u2014 you read report:42, report:43 just now: journal report link 44 \"<ref>\" for whichever it came from", "meta": {"from": "journal"}}
{"content": "sequence 8, Writing an update, step 3 of 3 - Answer with it \u2014 Reply in one short line, then the report's reference on a line of its own, like report 98, so the chat shows it as a card the user opens. Finish with journal sequence next 8 --about trigger:3. When it is done: journal sequence next 8 --about trigger:3", "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": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "meta": {"from": "journal"}}
{"content": "1 new message 9357 - answer by opening your turn with [!reply:9357]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "fact 22 \u2014 A shipped sequence change reaches existing journals only through a\u2026 \u2014 features/sequences/shipped.py ship() runs from migrations (m0022, m0028, m0029), and each migration runs once per record. Since 2026-09-24 ship() brings a system sequence's brief, start and steps in step with the code, but only when a migration calls it: a wording change needs a new mNNNN file that re-exports m0022's run.", "meta": {"from": "journal"}}
{"content": "work 1387 in hand \u2014 System sequences' triggers are locked and shown on the\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": "1 new message 9361 - answer by opening your turn with [!reply:9361]", "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": "1 new message 9363 - answer by opening your turn with [!reply:9363]", "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": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.; rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "request GET /api/main/dashboard is slower than its budget \u2014 223ms last (204ms of it working), against a budget of 50ms. Seen 912 times.", "meta": {"from": "journal"}}
{"content": "your message 9365 names 274 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 9365 \"<the text>\"; 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": "journal-dumps, journal-pinned-links, journal-triggers, journal-update-reports\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; message 9366 file Screenshot 2026-09-24 at 17.11.05.png needs tags \u2014 inspect the attachment, then journal message tag 9366 \"Screenshot 2026-09-24 at 17.11.05.png\" \"<a few words describing what it shows>\"; work 1387 is still open \u2014 end it or park it before you stop: journal work end 1387 --how \"<what landed>\", or journal work park 1387 \"<why it waits>\"; 1 new message 9366 - answer by opening your turn with [!reply:9366]; message 9366 updated", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "meta": {"from": "journal"}}
{"content": "1 new message 9371 - answer by opening your turn with [!reply:9371]", "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": "1 new message 9374 - answer by opening your turn with [!reply:9374]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 9377 - answer by opening your turn with [!reply:9377]", "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.; 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": "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.; 1 new message 9378 - answer by opening your turn with [!reply:9378]", "meta": {"from": "journal"}}
{"content": "1 new message 9380 - answer by opening your turn with [!reply:9380]", "meta": {"from": "journal"}}
{"content": "1 new message 9381 - answer by opening your turn with [!reply:9381]", "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": "auto mode is on and work 1389 stands still while todo 1589 is ready \u2014 if work 1389 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 1589. Stop only when nothing ready is left.; work 1389 is still open, with nothing logged \u2014 journal work log 1389 \"<what was decided or done, and why>\" \u2014 then journal work end 1389 --how \"<what landed>\", or journal work park 1389 \"<why it waits>\"", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 26bc85bb6 closed to-do 1589 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 290ms last (212ms of it working), against a budget of 50ms. Seen 920 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9391 - answer by opening your turn with [!reply:9391]", "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 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 9393 - answer by opening your turn with [!reply:9393]", "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": "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.; work 1390 is still open, with nothing logged \u2014 journal work log 1390 \"<what was decided or done, and why>\" \u2014 then journal work end 1390 --how \"<what landed>\", or journal work park 1390 \"<why it waits>\"", "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": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 6d4366688 closed to-do 1591 and ended work 1390 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "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": "message 9398 file Screenshot 2026-09-24 at 17.22.18.png needs tags \u2014 inspect the attachment, then journal message tag 9398 \"Screenshot 2026-09-24 at 17.22.18.png\" \"<a few words describing what it shows>\"; 1 new message 9398 - answer by opening your turn with [!reply:9398]; message 9398 updated; report 44 updated", "meta": {"from": "journal"}}
{"content": "1 new message 9401 - answer by opening your turn with [!reply:9401]", "meta": {"from": "journal"}}
{"content": "message 9401 file Screenshot 2026-09-24 at 17.24.40.png needs tags \u2014 inspect the attachment, then journal message tag 9401 \"Screenshot 2026-09-24 at 17.24.40.png\" \"<a few words describing what it shows>\"; message 9401 updated", "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": "1 new message 9402 - answer by opening your turn with [!reply:9402]", "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 9403 - answer by opening your turn with [!reply:9403]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 221ms last (159ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 921 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9404 - answer by opening your turn with [!reply:9404]", "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": "1 new message 9405 - answer by opening your turn with [!reply:9405]", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 71ms last (54ms of it working), against a budget of 50ms. Seen 32 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9410 - answer by opening your turn with [!reply:9410]", "meta": {"from": "journal"}}
{"content": "command message all is slower than its budget \u2014 117ms last (111ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "1 new message 9412 - answer by opening your turn with [!reply:9412]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 181ms last (161ms of it working), against a budget of 50ms. Seen 924 times.", "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": "message 9414 file Screenshot 2026-09-24 at 17.29.32.png needs tags \u2014 inspect the attachment, then journal message tag 9414 \"Screenshot 2026-09-24 at 17.29.32.png\" \"<a few words describing what it shows>\"; 1 new message 9414 - answer by opening your turn with [!reply:9414]; message 9414 updated", "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": "1 new message 9416 - answer by opening your turn with [!reply:9416]", "meta": {"from": "journal"}}
{"content": "1 new message 9417 - answer by opening your turn with [!reply:9417]", "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": "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": "answer message 9414 before you write anything \u2014 answer by opening your turn with [!reply:9414]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "message 9420 file Screenshot 2026-09-24 at 17.32.15.png needs tags \u2014 inspect the attachment, then journal message tag 9420 \"Screenshot 2026-09-24 at 17.32.15.png\" \"<a few words describing what it shows>\"; 1 new message 9420 - answer by opening your turn with [!reply:9420]; message 9420 updated", "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": "auto mode is on and work 1396 stands still while todo 1595 is ready \u2014 if work 1396 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 1595. Stop only when nothing ready is left.; work 1396 is still open, with nothing logged \u2014 journal work log 1396 \"<what was decided or done, and why>\" \u2014 then journal work end 1396 --how \"<what landed>\", or journal work park 1396 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9423 - answer by opening your turn with [!reply:9423]", "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": "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": "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": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.; 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": "commit cbd127e6c closed to-do 1595 \u2014 The rows and the work are done; take the next one.", "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": "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": "auto mode is on and work 1397 stands still while todo 1598 is ready \u2014 if work 1397 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 1598. Stop only when nothing ready is left.; work 1397 is still open \u2014 end it or park it before you stop: journal work end 1397 --how \"<what landed>\", or journal work park 1397 \"<why it waits>\"", "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 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": "commit 90a59fcf1 closed to-do 1599 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "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": "request GET /api/main/dashboard is slower than its budget \u2014 377ms last (201ms of it working), against a budget of 50ms. Seen 926 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9433 - answer by opening your turn with [!reply:9433]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "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": "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.; doc 53 cites nothing it was built on \u2014 you read report:44 just now: journal doc link 53 \"<ref>\" for whichever it came from", "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": "work 1400 is still open, with nothing logged \u2014 journal work log 1400 \"<what was decided or done, and why>\" \u2014 then journal work end 1400 --how \"<what landed>\", or journal work park 1400 \"<why it waits>\"; 1 new message 9438 - answer by opening your turn with [!reply:9438]", "meta": {"from": "journal"}}
{"content": "1 new message 9439 - answer by opening your turn with [!reply:9439]", "meta": {"from": "journal"}}
{"content": "1 new message 9440 - answer by opening your turn with [!reply:9440]; message 9440 deleted", "meta": {"from": "journal"}}
{"content": "1 new message 9441 - answer by opening your turn with [!reply:9441]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; 1 new message 9442 - answer by opening your turn with [!reply:9442]", "meta": {"from": "journal"}}
{"content": "1 new message 9445 - answer by opening your turn with [!reply:9445]", "meta": {"from": "journal"}}
{"content": "1 new message 9448 - answer by opening your turn with [!reply:9448]", "meta": {"from": "journal"}}
{"content": "1 new message 9449 - answer by opening your turn with [!reply:9449]", "meta": {"from": "journal"}}
{"content": "1 new comment 2033; doc 53 commented", "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": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 734ms last (105ms of it working), against a budget of 50ms. Seen 931 times.; 1 new message 9452 - answer by opening your turn with [!reply:9452]", "meta": {"from": "journal"}}
{"content": "work 1401 in hand \u2014 Build the proposal in doc 53 once the user approves it \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": "1 new message 9456 - answer by opening your turn with [!reply:9456]", "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": "1 new message 9458 - answer by opening your turn with [!reply:9458]", "meta": {"from": "journal"}}
{"content": "journal-boards, journal-dumps, journal-pinned-links, journal-triggers\u2026 \u2014 load one again when you next need it; only the every-start skills are held 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.", "meta": {"from": "journal"}}
{"content": "work 1401 is still open \u2014 end it or park it before you stop: journal work end 1401 --how \"<what landed>\", or journal work park 1401 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your message 9462 names 9456 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 9462 \"<the text>\"", "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 1401 stands still while todo 1601 is ready \u2014 if work 1401 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 1601. Stop only when nothing ready is left.; work 1401 is still open \u2014 end it or park it before you stop: journal work end 1401 --how \"<what landed>\", or journal work park 1401 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1401 stands still while todo 1601 is ready \u2014 if work 1401 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 1601. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit a152cd488 closed to-do 1600, to-do 1601, to-do 1602, to-do 1603 \u2014 The rows and the work are done; take the next one.", "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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 185ms last (163ms of it working), against a budget of 50ms. Seen 938 times.", "meta": {"from": "journal"}}
{"content": "work 1402 is still open \u2014 end it or park it before you stop: journal work end 1402 --how \"<what landed>\", or journal work park 1402 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "commit 86536e7cf closed to-do 1604 \u2014 The rows and the work are done; take the next one.; journal-boards, journal-dumps, journal-message-buttons, journal-pinned-links\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "1 new message 9477 - answer by opening your turn with [!reply:9477]", "meta": {"from": "journal"}}
{"content": "message 9478 file Screenshot 2026-09-24 at 17.55.29.png needs tags \u2014 inspect the attachment, then journal message tag 9478 \"Screenshot 2026-09-24 at 17.55.29.png\" \"<a few words describing what it shows>\"; 1 new message 9478 - answer by opening your turn with [!reply:9478]; message 9478 updated", "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": "1 new message 9480 - answer by opening your turn with [!reply:9480]", "meta": {"from": "journal"}}
{"content": "1 new message 9481 - answer by opening your turn with [!reply:9481]", "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": "work 1403 is still open, with nothing logged \u2014 journal work log 1403 \"<what was decided or done, and why>\" \u2014 then journal work end 1403 --how \"<what landed>\", or journal work park 1403 \"<why it waits>\"", "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": "commit 0c557c811 closed to-do 1605 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "message 9486 file Screenshot 2026-09-24 at 17.59.12.png needs tags \u2014 inspect the attachment, then journal message tag 9486 \"Screenshot 2026-09-24 at 17.59.12.png\" \"<a few words describing what it shows>\"; 1 new message 9486 - answer by opening your turn with [!reply:9486]; message 9486 updated", "meta": {"from": "journal"}}
{"content": "the user left dump 21 to you - finish it \u2014 take the next step you think best and file anything still open yourself, logging each step on the dump. Nothing waits for the user.; dump 21 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": "journal-boards, journal-message-buttons, journal-pinned-links\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "1 new message 9487 - answer by opening your turn with [!reply:9487]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 136ms last (56ms of it working), against a budget of 50ms. Seen 945 times.", "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": "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": "1 new message 9490 - answer by opening your turn with [!reply:9490]", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1405 stands still while todo 1607 is ready \u2014 if work 1405 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 1607. Stop only when nothing ready is left.; work 1405 is still open \u2014 end it or park it before you stop: journal work end 1405 --how \"<what landed>\", or journal work park 1405 \"<why it waits>\"", "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 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit a36d5b70f closed to-do 1606, to-do 1607 \u2014 The rows and the work are done; take the next one.; journal-boards, journal-command-tags, journal-message-buttons\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "message 9496 file Screenshot 2026-09-24 at 18.03.47.png needs tags \u2014 inspect the attachment, then journal message tag 9496 \"Screenshot 2026-09-24 at 18.03.47.png\" \"<a few words describing what it shows>\"; 1 new message 9496 - answer by opening your turn with [!reply:9496]; message 9496 updated", "meta": {"from": "journal"}}
{"content": "work 1406 is still open, with nothing logged \u2014 journal work log 1406 \"<what was decided or done, and why>\" \u2014 then journal work end 1406 --how \"<what landed>\", or journal work park 1406 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9499 - answer by opening your turn with [!reply:9499]", "meta": {"from": "journal"}}
{"content": "work 1407 is still open, with nothing logged \u2014 journal work log 1407 \"<what was decided or done, and why>\" \u2014 then journal work end 1407 --how \"<what landed>\", or journal work park 1407 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9501 - answer by opening your turn with [!reply:9501]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "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 command ran 32s 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 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": "request GET /api/main/dashboard is slower than its budget \u2014 60ms last (51ms of it working), against a budget of 50ms. Seen 948 times.", "meta": {"from": "journal"}}
{"content": "your message 9505 names 394 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 9505 \"<the text>\"", "meta": {"from": "journal"}}
{"content": "work 1408 is still open \u2014 end it or park it before you stop: journal work end 1408 --how \"<what landed>\", or journal work park 1408 \"<why it waits>\"", "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": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; message 9508 file Screenshot 2026-09-24 at 18.11.46.png needs tags \u2014 inspect the attachment, then journal message tag 9508 \"Screenshot 2026-09-24 at 18.11.46.png\" \"<a few words describing what it shows>\"; commit 623237c5e closed to-do 1608 \u2014 The rows and the work are done; take the next one.; 1 new message 9508 - answer by opening your turn with [!reply:9508]; message 9508 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": "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": "work 1409 is still open, with nothing logged \u2014 journal work log 1409 \"<what was decided or done, and why>\" \u2014 then journal work end 1409 --how \"<what landed>\", or journal work park 1409 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9512 - answer by opening your turn with [!reply:9512]", "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": "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": "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 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "work 1410 is still open, with nothing logged \u2014 journal work log 1410 \"<what was decided or done, and why>\" \u2014 then journal work end 1410 --how \"<what landed>\", or journal work park 1410 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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.; work 1410 is still open, with nothing logged \u2014 journal work log 1410 \"<what was decided or done, and why>\" \u2014 then journal work end 1410 --how \"<what landed>\", or journal work park 1410 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9516 - answer by opening your turn with [!reply:9516]; message 9516 updated", "meta": {"from": "journal"}}
{"content": "message 9516 file Screenshot 2026-09-24 at 18.16.59.png needs tags \u2014 inspect the attachment, then journal message tag 9516 \"Screenshot 2026-09-24 at 18.16.59.png\" \"<a few words describing what it shows>\"", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "request GET /api/main/dashboard is slower than its budget \u2014 117ms last (72ms of it working), against a budget of 50ms. Seen 951 times.", "meta": {"from": "journal"}}
{"content": "message 9518 file Screenshot 2026-09-24 at 18.18.12.png needs tags \u2014 inspect the attachment, then journal message tag 9518 \"Screenshot 2026-09-24 at 18.18.12.png\" \"<a few words describing what it shows>\"; 1 new message 9518 - answer by opening your turn with [!reply:9518]; message 9518 updated", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "meta": {"from": "journal"}}
{"content": "todo 1611 next", "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 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "work 1411 is still open \u2014 end it or park it before you stop: journal work end 1411 --how \"<what landed>\", or journal work park 1411 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "message 9525 file Screenshot 2026-09-24 at 18.19.55.png needs tags \u2014 inspect the attachment, then journal message tag 9525 \"Screenshot 2026-09-24 at 18.19.55.png\" \"<a few words describing what it shows>\"; 1 new message 9525 - answer by opening your turn with [!reply:9525]; message 9525 updated", "meta": {"from": "journal"}}
{"content": "your message 9526 names 1970 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 9526 \"<the text>\"; request GET /api/main/dashboard is slower than its budget \u2014 119ms last (55ms of it working), against a budget of 50ms. Seen 955 times.", "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": "question 147 completed", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1611, Project rows made at once never share a number under heavy load, is\u2026 \u2014 it is blocked because: Waits for the next failure's full output (which type and numbers); not reproducible in 25 loaded rounds. If it is not any more, journal todo unblock 1611. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1612, New work's waiting lines come in random order, is still blocked\u2026 \u2014 it is blocked because: Eileen, the designer subagent, is building it. If it is not any more, journal todo unblock 1612. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1613, New work's card typing speeds up and catches up once the agent has\u2026 \u2014 it is blocked because: Eileen, the designer subagent, is building it. If it is not any more, journal todo unblock 1613. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; command todo complete is slower than its budget \u2014 59ms last (54ms of it working), against a budget of 50ms. Seen 1 time.", "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": "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": "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.; 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": "request POST /api/run is slower than its budget \u2014 352ms last (90ms of it working), against a budget of 50ms. Seen 34 times.", "meta": {"from": "journal"}}
{"content": "2 new messages 9531, 9532 - answer each by opening a turn with [!reply:<n>]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; work 1413 is still open \u2014 end it or park it before you stop: journal work end 1413 --how \"<what landed>\", or journal work park 1413 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "message 9293 file Screenshot 2026-09-24 at 14.36.59.png needs tags \u2014 inspect the attachment, then journal message tag 9293 \"Screenshot 2026-09-24 at 14.36.59.png\" \"<a few words describing what it shows>\"; work 1413 is still open \u2014 end it or park it before you stop: journal work end 1413 --how \"<what landed>\", or journal work park 1413 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; 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": "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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 72ms last (51ms of it working), against a budget of 50ms. Seen 964 times.", "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": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1408, Share a journal with other users, is still blocked - is it still? \u2014 it is blocked because: Its plan, plan 15, waits for the user's approval. If it is not any more, journal todo unblock 1408. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 7a6d6d45c closed to-do 1612, to-do 1613, to-do 1615, to-do 1616, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "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": "message 9555 file Screenshot 2026-09-24 at 18.35.09.png needs tags \u2014 inspect the attachment, then journal message tag 9555 \"Screenshot 2026-09-24 at 18.35.09.png\" \"<a few words describing what it shows>\"; 1 new message 9555 - answer by opening your turn with [!reply:9555]; message 9555 updated", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "1 new message 9559 - answer by opening your turn with [!reply:9559]", "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": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "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 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": "question 146 completed", "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.", "meta": {"from": "journal"}}
{"content": "1 new message 9565 - answer by opening your turn with [!reply:9565]; message 9565 updated", "meta": {"from": "journal"}}
{"content": "message 9565 file Screenshot 2026-09-24 at 18.38.31.png needs tags \u2014 inspect the attachment, then journal message tag 9565 \"Screenshot 2026-09-24 at 18.38.31.png\" \"<a few words describing what it shows>\"; request GET /api/main/dashboard is slower than its budget \u2014 215ms last (51ms of it working), against a budget of 50ms. Seen 966 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": "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 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": "1 new message 9568 - answer by opening your turn with [!reply:9568]", "meta": {"from": "journal"}}
{"content": "1 new message 9569 - answer by opening your turn with [!reply:9569]", "meta": {"from": "journal"}}
{"content": "question 138 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.; 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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "1 new message 9575 - answer by opening your turn with [!reply:9575]", "meta": {"from": "journal"}}
{"content": "message 9578 file Screenshot 2026-09-24 at 18.38.31.png needs tags \u2014 inspect the attachment, then journal message tag 9578 \"Screenshot 2026-09-24 at 18.38.31.png\" \"<a few words describing what it shows>\"; 1 new message 9578 - answer by opening your turn with [!reply:9578]; message 9578 updated", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 448ms last (62ms of it working), against a budget of 50ms. Seen 970 times.; request GET /api/main/dashboard is slower than its budget \u2014 562ms last (67ms of it working), against a budget of 50ms. Seen 970 times.", "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": "question 94 completed", "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 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": "1 new message 9583 - answer by opening your turn with [!reply:9583]", "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": "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; journal-ask-questions changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for", "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": "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": "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 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 9590 - answer by opening your turn with [!reply:9590]", "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": "request GET /api/main/agent/34/links is slower than its budget \u2014 31033ms last (7285ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "1 new message 9591 - answer by opening your turn with [!reply:9591]", "meta": {"from": "journal"}}
{"content": "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": "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 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.", "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": "1 new message 9596 - answer by opening your turn with [!reply:9596]", "meta": {"from": "journal"}}
{"content": "1 new message 9597 - answer by opening your turn with [!reply:9597]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 158ms last (145ms of it working), against a budget of 50ms. Seen 972 times.", "meta": {"from": "journal"}}
{"content": "work 1416 in hand \u2014 The session bar's usage and context panels show every\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": "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 9602 - answer by opening your turn with [!reply:9602]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/doc is slower than its budget \u2014 55ms last (50ms of it working), against a budget of 50ms. Seen 1 time.", "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 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 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": "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": "1 new message 9606 - answer by opening your turn with [!reply:9606]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"I'm still waiting\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "1 new message 9609 - answer by opening your turn with [!reply:9609]; message 9609 updated", "meta": {"from": "journal"}}
{"content": "your wait for Otl finishing the question overlay height fix; the next release\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1417 stands still while todo 1611 is ready \u2014 if work 1417 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 1611. Stop only when nothing ready is left.; work 1417 is still open \u2014 end it or park it before you stop: journal work end 1417 --how \"<what landed>\", or journal work park 1417 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "the viewer threw Uncaught TypeError - Cannot read properties of null (reading\u2026 \u2014 Uncaught TypeError: Cannot read properties of null (reading 'style') http://127.0.0.1:8424/assets/index-BmRFoqA8.js:62 TypeError: Cannot read properties of null (reading 'style') at ResizeObserver.<anonymous> (http://127.0.0.1:8424/assets/index-BmRFoqA8.js:62:388) Seen 1 time.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1418 stands still while todo 1626 is ready \u2014 if work 1418 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 1626. Stop only when nothing ready is left.; work 1418 is still open, with nothing logged \u2014 journal work log 1418 \"<what was decided or done, and why>\" \u2014 then journal work end 1418 --how \"<what landed>\", or journal work park 1418 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "todo 1627 next", "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 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": "the viewer threw Uncaught TypeError - Cannot read properties of null (reading\u2026 \u2014 Uncaught TypeError: Cannot read properties of null (reading 'style') http://127.0.0.1:8424/assets/index-C6P3Fb26.js:62 TypeError: Cannot read properties of null (reading 'style') at ResizeObserver.<anonymous> (http://127.0.0.1:8424/assets/index-C6P3Fb26.js:62:388) Seen 1 time.", "meta": {"from": "journal"}}
{"content": "1 new message 9621 - answer by opening your turn with [!reply:9621]", "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.; request GET /api/main/dashboard is slower than its budget \u2014 264ms last (223ms of it working), against a budget of 50ms. Seen 986 times.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1419 stands still while todo 1631 is ready \u2014 if work 1419 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 1631. Stop only when nothing ready is left.; work 1419 is still open \u2014 end it or park it before you stop: journal work end 1419 --how \"<what landed>\", or journal work park 1419 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1627, Document comments in the inspector are elegant and a pleasure to\u2026 \u2014 it is blocked because: Dieter, the designer subagent, is building it. If it is not any more, journal todo unblock 1627. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1628, An agent writing a document is shown live in its inspector, is\u2026 \u2014 it is blocked because: Dieter, the designer subagent, is building it. If it is not any more, journal todo unblock 1628. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1629, The sequence inspector shows steps as a sequence, with a step\u2026 \u2014 it is blocked because: Dieter, the designer subagent, is building it. If it is not any more, journal todo unblock 1629. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; 1 new message 9625 - answer by opening your turn with [!reply:9625]", "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": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 197ms last (195ms of it working), against a budget of 50ms. Seen 1012 times.", "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": "commit ea3b274aa closed to-do 1632 \u2014 The rows and the work are done; take the next one.", "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": "1 new message 9634 - answer by opening your turn with [!reply:9634]", "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": "work 1420 in hand \u2014 A window's menu closes when its window moves or closes \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": "1 new message 9637 - answer by opening your turn with [!reply:9637]", "meta": {"from": "journal"}}
{"content": "1 new message 9640 - answer by opening your turn with [!reply:9640]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/doc is slower than its budget \u2014 97ms last (51ms of it working), against a budget of 50ms. Seen 3 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 108ms last (71ms of it working, 7ms collecting garbage), against a budget of 50ms. Seen 35 times.", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 178ms last (156ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 1023 times.", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "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": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "your command ran 32s 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; work 1422 in hand \u2014 Release 2.136.0 \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": "your wait for The suite for 2.136.0 and Dieter's clean point before the commit\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "1 new message 9654 - answer by opening your turn with [!reply:9654]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 3ae43e4c5 closed to-do 1627, to-do 1628 and ended work 1417 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "1 new message 9658 - answer by opening your turn with [!reply:9658]", "meta": {"from": "journal"}}
{"content": "answer message 9658 before you write anything \u2014 answer by opening your turn with [!reply:9658]. a reply, a reaction, or journal message processed <n>", "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": "check 3 failed - the same body is written 2 times, make it one funnel\u2026 \u2014 journal check show 3 says why; fix it, then journal check run 3", "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 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": "1 new message 9661 - answer by opening your turn with [!reply:9661]", "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": "your message 9662 names 9661 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 9662 \"<the text>\"; 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.; 1 new message 9663 - answer by opening your turn with [!reply:9663]", "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": "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 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 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": "work 1426 is still open, with nothing logged \u2014 journal work log 1426 \"<what was decided or done, and why>\" \u2014 then journal work end 1426 --how \"<what landed>\", or journal work park 1426 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9671 - answer by opening your turn with [!reply:9671]", "meta": {"from": "journal"}}
{"content": "1 new message 9672 - answer by opening your turn with [!reply:9672]", "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": "request GET /api/main/dashboard is slower than its budget \u2014 375ms last (310ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 1024 times.", "meta": {"from": "journal"}}
{"content": "commit d1068c4b6 closed to-do 1629 \u2014 The rows and the work are done; take the next one.", "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": "1 new message 9674 - answer by opening your turn with [!reply:9674]", "meta": {"from": "journal"}}
{"content": "the viewer threw ResizeObserver loop completed with undelivered notifications. \u2014 ResizeObserver loop completed with undelivered notifications. http://127.0.0.1:8424/#/main:0 Seen 4 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": "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": "message 9679 file Screenshot 2026-09-24 at 19.15.17.png needs tags \u2014 inspect the attachment, then journal message tag 9679 \"Screenshot 2026-09-24 at 19.15.17.png\" \"<a few words describing what it shows>\"; 1 new message 9679 - answer by opening your turn with [!reply:9679]; message 9679 updated", "meta": {"from": "journal"}}
{"content": "1 new message 9681 - answer by opening your turn with [!reply:9681]", "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": "request GET /api/main/dashboard is slower than its budget \u2014 174ms last (73ms of it working), against a budget of 50ms. Seen 1030 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": "1 new message 9683 - answer by opening your turn with [!reply:9683]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 9686 - answer by opening your turn with [!reply:9686]", "meta": {"from": "journal"}}
{"content": "work 1431 in hand \u2014 Presets keep every chosen option and can be shared and\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": "1 new message 9689 - answer by opening your turn with [!reply:9689]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 215ms last (193ms of it working), against a budget of 50ms. Seen 1034 times.", "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.; rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "1 new message 9690 - answer by opening your turn with [!reply:9690]", "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": "1 new message 9692 - answer by opening your turn with [!reply:9692]", "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": "work 1432 is still open \u2014 end it or park it before you stop: journal work end 1432 --how \"<what landed>\", or journal work park 1432 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread sequence 9", "meta": {"from": "journal"}}
{"content": "your wait for The full suite on the writing sequences, before installing and\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "sequence 9, Writing a document, step 2 of 4 - Write each chapter \u2014 Write the chapters one at a time and in order with journal doc section 55 \"<chapter>\" \"<body>\"; the user sees each one appear where you are. Cut a chapter that turned out empty with journal doc cut 55 \"<chapter>\". Then journal sequence next 9 --about doc:55. When it is done: journal sequence next 9 --about doc:55", "meta": {"from": "journal"}}
{"content": "sequence 9, Writing a document, step 3 of 4 - Offer the next step \u2014 If the document asks the user to decide or approve something, give it buttons: journal doc update 55 --set buttons='[{\"label\": \"Accept this proposal\", \"say\": \"I accept this proposal\"}, {\"label\": \"Change it first\", \"say\": \"I want changes first\"}]'. A button with say sends those words to you as the user's message; one naming a type, n and action runs that command. Skip this when nothing waits on the user. Then journal sequence next 9 --about doc:55. When it is done: journal sequence next 9 --about doc:55", "meta": {"from": "journal"}}
{"content": "sequence 9, Writing a document, step 4 of 4 - Answer with it \u2014 Say in one or two plain lines what the document concludes, then its reference on a line of its own, like `doc 41`. Finish with journal sequence next 9 --about doc:55. When it is done: journal sequence next 9 --about doc:55", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 143ms last (108ms of it working), against a budget of 50ms. Seen 1036 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9702 - answer by opening your turn with [!reply:9702]", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "1 new message 9703 - answer by opening your turn with [!reply:9703]; doc 55 updated", "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": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.; 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": "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": "1 new message 9705 - answer by opening your turn with [!reply:9705]", "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.; 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 9709 - answer by opening your turn with [!reply:9709]", "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": "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).; 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 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": "work 1427 in hand \u2014 Share a document with other people through a tunler link \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": "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": "auto mode is on and work 1427 stands still while todo 1644 is ready \u2014 if work 1427 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 1644. Stop only when nothing ready is left.; work 1427 is still open \u2014 end it or park it before you stop: journal work end 1427 --how \"<what landed>\", or journal work park 1427 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9719 - answer by opening your turn with [!reply:9719]; message 9719 updated", "meta": {"from": "journal"}}
{"content": "1 new message 9721 - answer by opening your turn with [!reply:9721]; message 9721 updated", "meta": {"from": "journal"}}
{"content": "your wait for The full suite on the sharing feature is over, because you are\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 96ms last (60ms of it working), against a budget of 50ms. Seen 36 times.", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "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 message 9723 names 280 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 9723 \"<the text>\"; 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 3a0a3b54a closed to-do 1643 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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 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": "work 1434 is still open \u2014 end it or park it before you stop: journal work end 1434 --how \"<what landed>\", or journal work park 1434 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your message 9734 names 280 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 9734 \"<the text>\"", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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 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": "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": "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; 1 new message 9758 - answer by opening your turn with [!reply:9758]", "meta": {"from": "journal"}}
{"content": "1 new message 9759 - answer by opening your turn with [!reply:9759]", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 132ms last (52ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 37 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9760 - answer by opening your turn with [!reply:9760]", "meta": {"from": "journal"}}
{"content": "your message 9761 names 280 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 9761 \"<the text>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9762 - answer by opening your turn with [!reply:9762]", "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": "journal 2.140.0 is out, this project runs 2.139.0 - run journal upgrade to install it", "meta": {"from": "journal"}}
{"content": "journal-ask-questions, journal-sharing changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "1 new message 9766 - answer by opening your turn with [!reply:9766]", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "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.; command todo find is slower than its budget \u2014 119ms last (51ms of it working), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9769 - answer by opening your turn with [!reply:9769]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 9772 - answer by opening your turn with [!reply:9772]", "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": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 4 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9775 - answer by opening your turn with [!reply:9775]", "meta": {"from": "journal"}}
{"content": "work 1438 in hand \u2014 The activity sidebar shows events only \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": "1 new message 9776 - answer by opening your turn with [!reply:9776]", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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": "request POST /api/main/message is slower than its budget \u2014 76ms last (59ms of it working), against a budget of 50ms. Seen 9 times.; 1 new message 9778 - answer by opening your turn with [!reply:9778]", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1647, An agent's share waits for the user's Accept, and shares can carry\u2026 \u2014 it is blocked because: Dieter, the designer subagent, is building the dialog's password field and waiting shares. If it is not any more, journal todo unblock 1647. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "command todo find is slower than its budget \u2014 2744ms last (327ms of it working), against a budget of 50ms. Seen 3 times.", "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.; 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.; 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": "request POST /api/run is slower than its budget \u2014 241ms last (66ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 39 times.", "meta": {"from": "journal"}}
{"content": "sequence 1, Filing a dump, step 1 of 3 - Read everything \u2014 journal dump items 22 lists what was dropped. Go through the items one at a time: read an item in full and at once record what it is with journal dump note 22 <item> \"<what it is>\", so the pile shows it as read, before you open the next. When the pasted text holds several things, such as a summary, a transcript and a link, split it with journal dump split 22 \"Summary, Transcript, Link\". Name its collection for what the pile is about with journal dump name 22 \"<name>\". When it is done: journal sequence next 1 --about dump:22; dump 22 has 1 item to file - journal dump items 22 \u2014 Load the journal-dumps skill first if it is not loaded. The Filing a dump sequence hands you its steps one at a time: follow each one and mark it done with journal sequence next, and it hands you the next. Tell the user what you do with journal dump log, and ask only in the dump window, never in the chat: the user is looking at the dump.; 1 new dump 22; 1 new collection 26; collection 26 linked; dump 22 linked", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 85ms last (53ms of it working), against a budget of 50ms. Seen 1056 times.", "meta": {"from": "journal"}}
{"content": "your message 9784 names 1653 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 9784 \"<the text>\"; rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "sequence 1, Filing a dump, step 2 of 3 - File by subject \u2014 Sort the pile by concern: one document per subject, never one big document, even when a single transcript or note covers several. Name each for what it is about, never after the file it came in. Decide the shape yourself: where a summary, meeting notes, the decisions or the action items would help, write them without being asked and list them with --added; action items become to-dos. An image goes with the document it belongs to. Never make a plan or start work: that is a suggestion for the end. Everything you file is in the journal at once, in the dump's collection. Log each step with journal dump log 22 \"<short title>\" --detail \"<what and why>\", with --making \"<type>, <title>\" before a row exists and --on <type:n> once it does. File each item as soon as you have what it needs, one at a time: journal dump filed 22 <item> \"<what you did>\" \"<ref, ref>\" --added \"dump:22\" or journal dump failed. Ask only what you cannot tell, with journal dump ask 22 \"<question>\" --guesses \"<one>|<two>\". When it is done: journal sequence next 1 --about dump:22", "meta": {"from": "journal"}}
{"content": "doc 56 cites nothing it was built on \u2014 you read report:45 just now: journal doc link 56 \"<ref>\" for whichever it came from", "meta": {"from": "journal"}}
{"content": "sequence 1, Filing a dump, step 3 of 3 - Sum up and suggest \u2014 Once every item is filed the dump closes. Sum up what you filed and where with journal dump offer 22 '[...]' --summary \"<two or three plain lines>\". Suggest up to four next steps only where one is worth taking, each a question with a button: {\"ask\": \"<question>\", \"label\": \"<button>\"}; use '[]' when there is nothing to suggest. The user takes or leaves each one. When it is done: journal sequence next 1 --about dump:22", "meta": {"from": "journal"}}
{"content": "dump 22 is filed (1 filed) - sum it up for the user \u2014 Everything it made is already in the journal, in the dump's collection. Sum up what you filed and where in two or three plain lines, and suggest a next step only where one is worth taking, as a question with a button on the dump itself, never elsewhere: journal dump offer 22 '[{\"ask\": \"The notes say you want to start on the mobile layout. Want me to plan it?\", \"label\": \"Plan it\"}]' --summary \"<what you filed and where>\". Use '[]' when nothing is worth suggesting. A step that is a journal action carries its type, n and action and runs as the user when pressed. Never start or plan anything yourself: a suggestion is how you propose it.", "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": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "dump 23 has 2 items to file - journal dump items 23 \u2014 Load the journal-dumps skill first if it is not loaded. The Filing a dump sequence hands you its steps one at a time: follow each one and mark it done with journal sequence next, and it hands you the next. Tell the user what you do with journal dump log, and ask only in the dump window, never in the chat: the user is looking at the dump.; dump 23 has 3 items to file - journal dump items 23 \u2014 Load the journal-dumps skill first if it is not loaded. The Filing a dump sequence hands you its steps one at a time: follow each one and mark it done with journal sequence next, and it hands you the next. Tell the user what you do with journal dump log, and ask only in the dump window, never in the chat: the user is looking at the dump.; sequence 1, Filing a dump, step 1 of 3 - Read everything \u2014 journal dump items 23 lists what was dropped. Go through the items one at a time: read an item in full and at once record what it is with journal dump note 23 <item> \"<what it is>\", so the pile shows it as read, before you open the next. When the pasted text holds several things, such as a summary, a transcript and a link, split it with journal dump split 23 \"Summary, Transcript, Link\". Name its collection for what the pile is about with journal dump name 23 \"<name>\". When it is done: journal sequence next 1 --about dump:23; dump 23 has 4 items to file - journal dump items 23 \u2014 Load the journal-dumps skill first if it is not loaded. The Filing a dump sequence hands you its steps one at a time: follow each one and mark it done with journal sequence next, and it hands you the next. Tell the user what you do with journal dump log, and ask only in the dump window, never in the chat: the user is looking at the dump.; dump 23 file WhatsApp Image 2026-09-24 at 19.24.23.jpeg needs tags \u2014 inspect the attachment, then journal dump tag 23 \"WhatsApp Image 2026-09-24 at 19.24.23.jpeg\" \"<a few words describing what it shows>\"; dump 23 file WhatsApp Image 2026-09-24 at 19.29.52.jpeg needs tags \u2014 inspect the attachment, then journal dump tag 23 \"WhatsApp Image 2026-09-24 at 19.29.52.jpeg\" \"<a few words describing what it shows>\"; 1 new dump 23; 1 new collection 27; collection 27 linked; dump 23 linked; dump 23 updated", "meta": {"from": "journal"}}
{"content": "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": "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 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.; sequence 1, Filing a dump, step 2 of 3 - File by subject \u2014 Sort the pile by concern: one document per subject, never one big document, even when a single transcript or note covers several. Name each for what it is about, never after the file it came in. Decide the shape yourself: where a summary, meeting notes, the decisions or the action items would help, write them without being asked and list them with --added; action items become to-dos. An image goes with the document it belongs to. Never make a plan or start work: that is a suggestion for the end. Everything you file is in the journal at once, in the dump's collection. Log each step with journal dump log 23 \"<short title>\" --detail \"<what and why>\", with --making \"<type>, <title>\" before a row exists and --on <type:n> once it does. File each item as soon as you have what it needs, one at a time: journal dump filed 23 <item> \"<what you did>\" \"<ref, ref>\" --added \"dump:23\" or journal dump failed. Ask only what you cannot tell, with journal dump ask 23 \"<question>\" --guesses \"<one>|<two>\". When it is done: journal sequence next 1 --about dump:23", "meta": {"from": "journal"}}
{"content": "journal-ask-questions, journal-dumps, journal-sharing changed since you loaded\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "doc 57 cites nothing it was built on \u2014 you read report:45, doc:56 just now: journal doc link 57 \"<ref>\" for whichever it came from", "meta": {"from": "journal"}}
{"content": "dump 23 is filed (4 filed) - sum it up for the user \u2014 Everything it made is already in the journal, in the dump's collection. Sum up what you filed and where in two or three plain lines, and suggest a next step only where one is worth taking, as a question with a button on the dump itself, never elsewhere: journal dump offer 23 '[{\"ask\": \"The notes say you want to start on the mobile layout. Want me to plan it?\", \"label\": \"Plan it\"}]' --summary \"<what you filed and where>\". Use '[]' when nothing is worth suggesting. A step that is a journal action carries its type, n and action and runs as the user when pressed. Never start or plan anything yourself: a suggestion is how you propose it.; sequence 1, Filing a dump, step 3 of 3 - Sum up and suggest \u2014 Once every item is filed the dump closes. Sum up what you filed and where with journal dump offer 23 '[...]' --summary \"<two or three plain lines>\". Suggest up to four next steps only where one is worth taking, each a question with a button: {\"ask\": \"<question>\", \"label\": \"<button>\"}; use '[]' when there is nothing to suggest. The user takes or leaves each one. When it is done: journal sequence next 1 --about dump:23", "meta": {"from": "journal"}}
{"content": "the user chose Compare the models for dump 23 \u2014 carry that step out, and log it on the dump.; dump 23 updated", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 442ms last (348ms of it working), against a budget of 50ms. Seen 1060 times.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 1 of 3 - Write the findings \u2014 Lead with the answer in the report's brief, then write each part with journal report section 46 \"<part>\" \"<body>\": the evidence, what was already sound, what remains uncertain. Then journal sequence next 10 --about report:46. When it is done: journal sequence next 10 --about report:46; report 46 cites nothing it was built on \u2014 you read report:45 just now: journal report link 46 \"<ref>\" for whichever it came from", "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).; 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.; sequence 10, Writing a report, step 2 of 3 - Offer the next step \u2014 If the report leads to something the user should decide, give it buttons: journal report update 46 --set buttons='[{\"label\": \"<the step>\", \"say\": \"<the words it sends>\"}]'. Skip this when nothing waits on the user. Then journal sequence next 10 --about report:46. When it is done: journal sequence next 10 --about report:46", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 3 of 3 - Answer with it \u2014 Say in one or two plain lines what the report found, then its reference on a line of its own, like `report 98`. Finish with journal sequence next 10 --about report:46. When it is done: journal sequence next 10 --about report:46", "meta": {"from": "journal"}}
{"content": "answer message 9760 before you write anything \u2014 answer by opening your turn with [!reply:9760]. a reply, a reaction, or journal message processed <n>; todo 1648 next; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.", "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": "check 2 failed - web/src/share/ShareApp.vue -35 names an endpoint outside\u2026 \u2014 journal check show 2 says why; fix it, then journal check run 2", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "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": "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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 1674ms last (506ms of it working), against a budget of 50ms. Seen 1061 times.", "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 9810 - answer by opening your turn with [!reply:9810]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "command message create is slower than its budget \u2014 94ms last (69ms of it working), against a budget of 50ms. Seen 2 times.; request POST /api/run is slower than its budget \u2014 112ms last (81ms of it working), against a budget of 50ms. Seen 41 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": "request GET /api/main/agent is slower than its budget \u2014 892ms last (55ms of it working, 7ms collecting garbage), against a budget of 50ms. Seen 20 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9814 - answer by opening your turn with [!reply:9814]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 156ms last (81ms of it working), against a budget of 50ms. Seen 10 times.", "meta": {"from": "journal"}}
{"content": "1 new share 2", "meta": {"from": "journal"}}
{"content": "1 new message 9818 - answer by opening your turn with [!reply:9818]", "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.", "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": "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": "waiting: 1 unread share 2", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1446 stands still while todo 1648 is ready \u2014 if work 1446 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 1648. Stop only when nothing ready is left.; work 1446 is still open \u2014 end it or park it before you stop: journal work end 1446 --how \"<what landed>\", or journal work park 1446 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 5 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9823 - answer by opening your turn with [!reply:9823]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 1938ms last (524ms of it working), against a budget of 50ms. Seen 1071 times.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; 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": "1 new message 9824 - answer by opening your turn with [!reply:9824]", "meta": {"from": "journal"}}
{"content": "1 new message 9826 - answer by opening your turn with [!reply:9826]", "meta": {"from": "journal"}}
{"content": "message 9826 file Screenshot 2026-09-24 at 20.21.31.png needs tags \u2014 inspect the attachment, then journal message tag 9826 \"Screenshot 2026-09-24 at 20.21.31.png\" \"<a few words describing what it shows>\"; message 9826 updated", "meta": {"from": "journal"}}
{"content": "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.", "meta": {"from": "journal"}}
{"content": "1 new message 9827 - answer by opening your turn with [!reply:9827]", "meta": {"from": "journal"}}
{"content": "1 new message 9829 - answer by opening your turn with [!reply:9829]", "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": "your command ran 32s 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 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 9832 - answer by opening your turn with [!reply:9832]", "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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "1 new message 9837 - answer by opening your turn with [!reply:9837]", "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": "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": "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; request POST /api/main/message is slower than its budget \u2014 124ms last (77ms of it working), against a budget of 50ms. Seen 14 times.; 1 new message 9838 - answer by opening your turn with [!reply:9838]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 2785ms last (484ms of it working), against a budget of 50ms. Seen 1080 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.", "meta": {"from": "journal"}}
{"content": "1 new message 9840 - answer by opening your turn with [!reply:9840]", "meta": {"from": "journal"}}
{"content": "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": "work 1449 in hand \u2014 Reports can be shared \u2014 if this is not what you are doing, end it or park it and start the work you are in; work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "1 new message 9843 - answer by opening your turn with [!reply:9843]", "meta": {"from": "journal"}}
{"content": "1 new message 9844 - answer by opening your turn with [!reply:9844]", "meta": {"from": "journal"}}
{"content": "1 new comment 2120; report 46 commented", "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": "1 new message 9845 - answer by opening your turn with [!reply:9845]", "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": "your command ran 32s 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 9848 - answer by opening your turn with [!reply:9848]", "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": "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": "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": "auto mode is on and work 1450 stands still while todo 1649 is ready \u2014 if work 1450 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 1649. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "work 1450 is still open, with nothing logged \u2014 journal work log 1450 \"<what was decided or done, and why>\" \u2014 then journal work end 1450 --how \"<what landed>\", or journal work park 1450 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.", "meta": {"from": "journal"}}
{"content": "1 new message 9855 - answer by opening your turn with [!reply:9855]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 169ms last (78ms of it working), against a budget of 50ms. Seen 1082 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9859 - answer by opening your turn with [!reply:9859]", "meta": {"from": "journal"}}
{"content": "1 new message 9860 - answer by opening your turn with [!reply:9860]", "meta": {"from": "journal"}}
{"content": "todo 1655, A ticket runs its own orchestrator agent instead of an assignee, is\u2026 \u2014 it is blocked because: Waits for the user's choice on report 46 (Go with your picks, or talk it through first). If it is not any more, journal todo unblock 1655. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1656, The board shows domains and roles with their active agents and\u2026 \u2014 it is blocked because: Waits for the user's choice on report 46 (Go with your picks, or talk it through first). If it is not any more, journal todo unblock 1656. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1657, Weigh Redmar's plan and ticket orchestration model, is still\u2026 \u2014 it is blocked because: Waits for the user's choice on report 46 (Go with your picks, or talk it through first). If it is not any more, journal todo unblock 1657. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1666, A comment shows the instant it is posted, is still blocked - is it\u2026 \u2014 it is blocked because: Dieter, the designer subagent, is building it. If it is not any more, journal todo unblock 1666. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; 1 new message 9862 - answer by opening your turn with [!reply:9862]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 9864 - answer by opening your turn with [!reply:9864]", "meta": {"from": "journal"}}
{"content": "journal-ask-questions, journal-command-tags, journal-dumps, journal-sharing\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/edits is slower than its budget \u2014 1045ms last (85ms of it working, 17ms collecting garbage), against a budget of 50ms. Seen 5 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9865 - answer by opening your turn with [!reply:9865]", "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": "1 new message 9869 - answer by opening your turn with [!reply:9869]", "meta": {"from": "journal"}}
{"content": "1 new message 9870 - answer by opening your turn with [!reply:9870]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/doc is slower than its budget \u2014 225ms last (109ms of it working), against a budget of 50ms. Seen 4 times.; request GET /api/main/dashboard is slower than its budget \u2014 420ms last (242ms of it working, 8ms collecting garbage), against a budget of 50ms. Seen 1086 times.", "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": "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 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": "1 new message 9874 - answer by opening your turn with [!reply:9874]; message 9874 updated", "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 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": "the user put \ud83d\udc4d on comment 2129 - act on it if it asks for something, such as a go-ahead. It needs no reply, and the chat never mentions it", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/links is slower than its budget \u2014 1077ms last (298ms of it working), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 903ms last (51ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 36 times.", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 297ms last (58ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 346ms last (80ms of it working), against a budget of 50ms. Seen 42 times.", "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": "request POST /api/main/message is slower than its budget \u2014 187ms last (57ms of it working), against a budget of 50ms. Seen 15 times.; message 9875 file Screenshot 2026-09-24 at 20.46.36.png needs tags \u2014 inspect the attachment, then journal message tag 9875 \"Screenshot 2026-09-24 at 20.46.36.png\" \"<a few words describing what it shows>\"; 1 new message 9875 - answer by opening your turn with [!reply:9875]; message 9875 updated", "meta": {"from": "journal"}}
{"content": "message 9881 file Screenshot 2026-09-24 at 20.54.21.png needs tags \u2014 inspect the attachment, then journal message tag 9881 \"Screenshot 2026-09-24 at 20.54.21.png\" \"<a few words describing what it shows>\"; 1 new message 9881 - answer by opening your turn with [!reply:9881]; message 9881 updated", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 9883 - answer by opening your turn with [!reply:9883]", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "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": "share 2 completed", "meta": {"from": "journal"}}
{"content": "1 new share 3", "meta": {"from": "journal"}}
{"content": "1 new message 9884 - answer by opening your turn with [!reply:9884]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 1464ms last (60ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 21 times.", "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; the viewer threw The user aborted a request. \u2014 The user aborted a request. / Seen 2 times.", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "sequence 10, Writing a report, step 1 of 3 - Write the findings \u2014 Lead with the answer in the report's brief, then write each part with journal report section 47 \"<part>\" \"<body>\": the evidence, what was already sound, what remains uncertain. Then journal sequence next 10 --about report:47. When it is done: journal sequence next 10 --about report:47", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 2 of 3 - Offer the next step \u2014 If the report leads to something the user should decide, give it buttons: journal report update 47 --set buttons='[{\"label\": \"<the step>\", \"say\": \"<the words it sends>\"}]'. Skip this when nothing waits on the user. Then journal sequence next 10 --about report:47. When it is done: journal sequence next 10 --about report:47", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 618ms last (290ms of it working), against a budget of 50ms. Seen 1116 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.; sequence 10, Writing a report, step 3 of 3 - Answer with it \u2014 Say in one or two plain lines what the report found, then its reference on a line of its own, like `report 98`. Finish with journal sequence next 10 --about report:47. When it is done: journal sequence next 10 --about report:47", "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": "request GET /api/summary is slower than its budget \u2014 595ms last (57ms of it working), against a budget of 50ms. Seen 83 times.", "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 9896 - answer by opening your turn with [!reply:9896]", "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": "work 1457 in hand \u2014 A journal moves off a port another project's journal\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": "request GET /api/main/dashboard is slower than its budget \u2014 2675ms last (455ms of it working), against a budget of 50ms. Seen 1122 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 298ms last (90ms of it working), against a budget of 50ms. Seen 20 times.; 1 new message 9903 - answer by opening your turn with [!reply:9903]", "meta": {"from": "journal"}}
{"content": "1 new message 9904 - answer by opening your turn with [!reply:9904]", "meta": {"from": "journal"}}
{"content": "sequence 8, Writing an update, step 1 of 3 - See what changed \u2014 journal report changes lists what happened since the user last opened an update, under need, done, doing, plans, commits and also. Read any row you do not remember before you sum it up. Then journal sequence next 8 --about trigger:3. When it is done: journal sequence next 8 --about trigger:3", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"Reading your message first\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead; 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": "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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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.; sequence 8, Writing an update, step 2 of 3 - Write the update \u2014 journal report recap \"<one or two plain sentences: what got done, what is under way, what waits on the user>\" writes the report with those rows in that order. Give every row under need and doing a short note of what it waits on or what is being done now: journal report note <report n> <row> \"<line>\". Add a row the list missed with journal report item <report n> <section> <row> \"<title>\", and take out one that is only noise with journal report drop <report n> <row>. Then journal sequence next 8 --about trigger:3. When it is done: journal sequence next 8 --about trigger:3", "meta": {"from": "journal"}}
{"content": "report 48 cites nothing it was built on \u2014 you read report:47 just now: journal report link 48 \"<ref>\" for whichever it came from", "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 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 8, Writing an update, step 3 of 3 - Answer with it \u2014 Reply in one short line that says the update is pinned at the bottom of the chat, like \"Here's the update; I pinned it at the bottom of the chat.\", then the report's reference on a line of its own, like `report 98`, so the chat shows it as a card the user opens. Finish with journal sequence next 8 --about trigger:3. When it is done: journal sequence next 8 --about trigger:3", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread share 3", "meta": {"from": "journal"}}
{"content": "1 new message 9907 - answer by opening your turn with [!reply:9907]", "meta": {"from": "journal"}}
{"content": "1 new message 9909 - answer by opening your turn with [!reply:9909]", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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; your wait for The full suite on everything since 2.142.0, then the 2.143.0\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "1 new message 9911 - answer by opening your turn with [!reply:9911]", "meta": {"from": "journal"}}
{"content": "1 new message 9912 - answer by opening your turn with [!reply:9912]", "meta": {"from": "journal"}}
{"content": "report 48 updated", "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": "work 1451 in hand \u2014 A long command's mark times its run and ends when the\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": "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": "request POST /api/run is slower than its budget \u2014 139ms last (97ms of it working), against a budget of 50ms. Seen 46 times.", "meta": {"from": "journal"}}
{"content": "your wait for The build and install of the mark's new look, then checking the\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting; request GET /api/main/dashboard is slower than its budget \u2014 660ms last (88ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 1132 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 910ms last (52ms of it working), against a budget of 50ms. Seen 23 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 103ms last (78ms of it working), against a budget of 50ms. Seen 22 times.; 1 new message 9915 - answer by opening your turn with [!reply:9915]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; auto mode is on and work 1451 stands still while todo 1664 is ready \u2014 if work 1451 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 1664. Stop only when nothing ready is left.; message 9542 file Screenshot 2026-09-24 at 18.28.39.png needs tags \u2014 inspect the attachment, then journal message tag 9542 \"Screenshot 2026-09-24 at 18.28.39.png\" \"<a few words describing what it shows>\"; message 9719 file Screenshot 2026-09-24 at 19.30.37.png needs tags \u2014 inspect the attachment, then journal message tag 9719 \"Screenshot 2026-09-24 at 19.30.37.png\" \"<a few words describing what it shows>\"; work 1451 is still open, with nothing logged \u2014 journal work log 1451 \"<what was decided or done, and why>\" \u2014 then journal work end 1451 --how \"<what landed>\", or journal work park 1451 \"<why it waits>\"", "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": "you ran the same check 3 times in a row - cd\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.", "meta": {"from": "journal"}}
{"content": "you ran the same check 3 times in a row - cd\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.", "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": "1 new message 9918 - answer by opening your turn with [!reply:9918]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; you ran the same check 3 times in a row - cd\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.", "meta": {"from": "journal"}}
{"content": "todo 1664 next; command message reply is slower than its budget \u2014 236ms last (117ms of it working), against a budget of 50ms. Seen 4 times.", "meta": {"from": "journal"}}
{"content": "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.; 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.; rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 9921 - answer by opening your turn with [!reply:9921]", "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": "that Edit call returned 691,602 characters, the largest this session \u2014 It stays in the context for good. If you were looking for one thing in it, the next read can be narrower: grep for the line, sed a range, head the file.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1458 stands still while todo 1664 is ready \u2014 if work 1458 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 1664. Stop only when nothing ready is left.; work 1458 is still open \u2014 end it or park it before you stop: journal work end 1458 --how \"<what landed>\", or journal work park 1458 \"<why it waits>\"", "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 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": "request GET /api/main/dashboard is slower than its budget \u2014 171ms last (65ms of it working), against a budget of 50ms. Seen 1134 times.", "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 9925 - answer by opening your turn with [!reply:9925]", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1458 stands still while todo 1664 is ready \u2014 if work 1458 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 1664. Stop only when nothing ready is left.; work 1458 is still open \u2014 end it or park it before you stop: journal work end 1458 --how \"<what landed>\", or journal work park 1458 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 9927 - answer by opening your turn with [!reply:9927]; message 9927 updated", "meta": {"from": "journal"}}
{"content": "your wait for The full suite run before the 2.143.0 release commit is over\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 7 times.", "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": "auto mode is on and work 1459 stands still while todo 1664 is ready \u2014 if work 1459 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 1664. Stop only when nothing ready is left.; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.; work 1459 is still open, with nothing logged \u2014 journal work log 1459 \"<what was decided or done, and why>\" \u2014 then journal work end 1459 --how \"<what landed>\", or journal work park 1459 \"<why it waits>\"; 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 9931 - answer by opening your turn with [!reply:9931]", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1460 stands still while todo 1667 is ready \u2014 if work 1460 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 1667. Stop only when nothing ready is left.; work 1460 is still open, with nothing logged \u2014 journal work log 1460 \"<what was decided or done, and why>\" \u2014 then journal work end 1460 --how \"<what landed>\", or journal work park 1460 \"<why it waits>\"", "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": "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.", "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": "request POST /api/main/message is slower than its budget \u2014 76ms last (68ms of it working), against a budget of 50ms. Seen 23 times.; 1 new message 9938 - answer by opening your turn with [!reply:9938]", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 141ms last (62ms of it working), against a budget of 50ms. Seen 6 times.; work 1460 is still open, with nothing logged \u2014 journal work log 1460 \"<what was decided or done, and why>\" \u2014 then journal work end 1460 --how \"<what landed>\", or journal work park 1460 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1460 stands still while todo 1674 is ready \u2014 if work 1460 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 1674. Stop only when nothing ready is left.", "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": "request GET /api/main/dashboard is slower than its budget \u2014 191ms last (64ms of it working), against a budget of 50ms. Seen 1139 times.", "meta": {"from": "journal"}}
{"content": "1 new message 9941 - answer by opening your turn with [!reply:9941]", "meta": {"from": "journal"}}
{"content": "1 new message 9942 - answer by opening your turn with [!reply:9942]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; auto mode is on and work 1461 stands still while todo 1667 is ready \u2014 if work 1461 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 1667. Stop only when nothing ready is left.; work 1461 is still open, with nothing logged \u2014 journal work log 1461 \"<what was decided or done, and why>\" \u2014 then journal work end 1461 --how \"<what landed>\", or journal work park 1461 \"<why it waits>\"; 1 new message 9943 - answer by opening your turn with [!reply:9943]", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1461 stands still while todo 1667 is ready \u2014 if work 1461 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 1667. Stop only when nothing ready is left.; work 1461 is still open, with nothing logged \u2014 journal work log 1461 \"<what was decided or done, and why>\" \u2014 then journal work end 1461 --how \"<what landed>\", or journal work park 1461 \"<why it waits>\"", "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 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "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": "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 user put \u2764\ufe0f on comment 2148 - act on it if it asks for something, such as a go-ahead. It needs no reply, and the chat never mentions it", "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 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.; request GET /api/main/dashboard is slower than its budget \u2014 204ms last (114ms of it working), against a budget of 50ms. Seen 1141 times.", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 9953 - answer by opening your turn with [!reply:9953]", "meta": {"from": "journal"}}
{"content": "answer message 9953 before you write anything \u2014 answer by opening your turn with [!reply:9953]. a reply, a reaction, or journal message processed <n>; rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "auto mode is on and work 1462 stands still while todo 1667 is ready \u2014 if work 1462 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 1667. Stop only when nothing ready is left.; work 1462 is still open, with nothing logged \u2014 journal work log 1462 \"<what was decided or done, and why>\" \u2014 then journal work end 1462 --how \"<what landed>\", or journal work park 1462 \"<why it waits>\"", "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": "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": "1 new message 9958 - answer by opening your turn with [!reply:9958]", "meta": {"from": "journal"}}
{"content": "plugin 17 completed", "meta": {"from": "journal"}}
{"content": "work 1462 in hand \u2014 Plans can be shared with their live progress \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": "request POST /api/run is slower than its budget \u2014 251ms last (82ms of it working), against a budget of 50ms. Seen 47 times.; 1 new plugin 18", "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": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "1 new message 9962 - answer by opening your turn with [!reply:9962]", "meta": {"from": "journal"}}
{"content": "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": "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.; 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 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": "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 9990 - answer by opening your turn with [!reply:9990]", "meta": {"from": "journal"}}
{"content": "the viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 97 times.", "meta": {"from": "journal"}}
{"content": "the user put \u2764\ufe0f on comment 2152 - act on it if it asks for something, such as a go-ahead. It needs no reply, and the chat never mentions it", "meta": {"from": "journal"}}
{"content": "work 1463 in hand \u2014 Release 2.144.0 \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": "request GET /api/main/dashboard is slower than its budget \u2014 218ms last (51ms of it working), against a budget of 50ms. Seen 1149 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 80ms last (70ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "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 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": "1 new message 9995 - answer by opening your turn with [!reply:9995]", "meta": {"from": "journal"}}
{"content": "1 new message 9996 - answer by opening your turn with [!reply:9996]", "meta": {"from": "journal"}}
{"content": "message 9996 updated", "meta": {"from": "journal"}}
{"content": "message 9996 updated", "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": "your wait for The designer's gradient fix on the plugin cards, then the final\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "1 new message 10003 - answer by opening your turn with [!reply:10003]", "meta": {"from": "journal"}}
{"content": "message 10003 updated", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 212ms last (59ms of it working), against a budget of 50ms. Seen 1150 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 173ms last (54ms of it working), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10006 - answer by opening your turn with [!reply:10006]", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 150ms last (91ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 50 times.", "meta": {"from": "journal"}}
{"content": "Code Commandments found 156 sins across 14 skills. \u2014 journal check show 26 says why; fix it, then journal check run 26", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 the files changed since the last check (`host.py`, `parts.p\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`host.py`, `parts.py`, `source.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-positional-tuple-return at /Users/jessegall/projects/agent-journal/src/features/plugins/parts.py:54 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "the viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 98 times.", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "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 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": "request GET /api/summary is slower than its budget \u2014 360ms last (52ms of it working), against a budget of 50ms. Seen 4 times.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; Code Commandments \u2014 before you commit \u2014 you've changed 7 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 7 judged files since the last commit. Consider running `vendor/bin/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": "sequence 2, Building a plan, step 1 of 4 - Name the goal \u2014 Settle with the user what is true when the plan is done, and set it as the plan's goal. When it is done: journal sequence next 2 --about plan:16; plan 16 is building - add its phases \u2014 journal plan phase 16 \"<title>\" --when \"<complete when>\" for each phase, --checkpoint where the user should look; then journal plan stage 16 todos", "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": "request POST /api/run is slower than its budget \u2014 112ms last (78ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 51 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 897ms last (85ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 1155 times.", "meta": {"from": "journal"}}
{"content": "you ran the same check 3 times in a row - cd\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.; sequence 2, Building a plan, step 2 of 4 - Add the phases \u2014 Add every phase in order with journal plan phase 16 \"<title>\" --when \"<complete when>\", and --checkpoint where the user should look before it goes on. When it is done: journal sequence next 2 --about plan:16; plan 16 is at its to-dos \u2014 file each phase's rows and put them under it with journal plan todos 16 <phase> <rows...>; when every phase has rows, journal plan ready 16", "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 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.", "meta": {"from": "journal"}}
{"content": "every phase of plan 16 has its to-dos \u2014 journal plan ready 16 hands it to the user, who approves it", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1655, A ticket runs its own orchestrator agent instead of an assignee, is\u2026 \u2014 it is blocked because: Waits for the user's choice on report 46 (Go with your picks, or talk it through first). If it is not any more, journal todo unblock 1655. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1656, The board shows domains and roles with their active agents and\u2026 \u2014 it is blocked because: Waits for the user's choice on report 46 (Go with your picks, or talk it through first). If it is not any more, journal todo unblock 1656. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1666, A comment shows the instant it is posted, is still blocked - is it\u2026 \u2014 it is blocked because: Dieter, the designer subagent, is building it. If it is not any more, journal todo unblock 1666. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1684, Sin marks in the chat, yellow when found and green only once fixed\u2026 \u2014 it is blocked because: Waiting on the Code Commandments session to pass --env on its queued raises and key marks by sin id. If it is not any more, journal todo unblock 1684. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; sequence 2, Building a plan, step 3 of 4 - File the rows \u2014 journal plan stage 16 todos, then file the to-dos and put each under its phase with journal plan todos 16 <phase> <rows>. When it is done: journal sequence next 2 --about plan:16; sequence 2, Building a plan, step 4 of 4 - Hand it over \u2014 When every phase has rows, journal plan ready 16. Only the user approves it; you start it when they have. When it is done: journal sequence next 2 --about plan:16", "meta": {"from": "journal"}}
{"content": "todo 1667 next; 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": "the viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 101 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.", "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": "Code Commandments \u2014 the files changed since the last check (`shipped.py`, `hand\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`shipped.py`, `handlers.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/src/features/sequences/shipped.py:12; python-dict-bag at /Users/jessegall/projects/agent-journal/src/features/sequences/shipped.py:324; python-dict-bag at /Users/jessegall/projects/agent-journal/src/features/sequences/shipped.py:325 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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 `shipped.py`, changed since the last check, breaks a rule.\u2026 \u2014 Code Commandments \u2014 `shipped.py`, changed since the last check, 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/src/features/sequences/shipped.py:326 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "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.; 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.; rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "that Edit call returned 693,953 characters, the largest this session \u2014 It stays in the context for good. If you were looking for one thing in it, the next read can be narrower: grep for the line, sed a range, head the file.", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "Code Commandments \u2014 before you commit \u2014 you've changed 5 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 5 judged files since the last commit. Consider running `vendor/bin/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 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 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": "commit 7b2798bd2 closed to-do 1667 and ended work 1466 \u2014 The rows and the work are done; take the next one.; journal-sequences, journal-sharing changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 128ms last (85ms of it working), against a budget of 50ms. Seen 1158 times.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 `controller.py`, changed since the last check, breaks a rul\u2026 \u2014 Code Commandments \u2014 `controller.py`, changed since the last check, breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-dict-return-bag at /Users/jessegall/projects/agent-journal/src/features/plans/controller.py:28 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "the viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 104 times.", "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": "1 new message 10032 - answer by opening your turn with [!reply:10032]", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 168ms last (64ms of it working), against a budget of 50ms. Seen 52 times.", "meta": {"from": "journal"}}
{"content": "the user approved plan 16, Redmar's orchestration model - start it \u2014 journal plan start 16 makes it active and parks a plan that runs; then work its first phase's rows in order; 1 new message 10033 - answer by opening your turn with [!reply:10033]; plan 16 updated", "meta": {"from": "journal"}}
{"content": "1 new message 10036 - answer by opening your turn with [!reply:10036]", "meta": {"from": "journal"}}
{"content": "1 new message 10038 - answer by opening your turn with [!reply:10038]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 811ms last (75ms of it working), against a budget of 50ms. Seen 1162 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10039 - answer by opening your turn with [!reply:10039]", "meta": {"from": "journal"}}
{"content": "work 1467 in hand \u2014 A plan's timeline of work across its to-dos, beside the\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": "the viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 106 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10045 - answer by opening your turn with [!reply:10045]", "meta": {"from": "journal"}}
{"content": "1 new message 10046 - answer by opening your turn with [!reply:10046]", "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": "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": "Code Commandments \u2014 before you commit \u2014 you've changed 8 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 8 judged files since the last commit. Consider running `vendor/bin/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 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": "waiting: 1 unread sequence 11", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread sequence 11", "meta": {"from": "journal"}}
{"content": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 1 times (codes 000)", "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": "your wait for The suite, then the 2.146.0 commit, tag, push and install is\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; 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 `vendor/bin/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 await tag on did not run \u2014 ! nothing is open: journal work start \"<the work>\" first - add what is missing to the tag itself; todo 1655 next", "meta": {"from": "journal"}}
{"content": "todo 1655 next", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1468 stands still while todo 1656 is ready \u2014 if work 1468 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 1656. Stop only when nothing ready is left.; work 1468 is still open, with nothing logged \u2014 journal work log 1468 \"<what was decided or done, and why>\" \u2014 then journal work end 1468 --how \"<what landed>\", or journal work park 1468 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "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": "1 new message 10055 - answer by opening your turn with [!reply:10055]", "meta": {"from": "journal"}}
{"content": "1 new message 10056 - answer by opening your turn with [!reply:10056]", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"reply went out\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "1 new message 10060 - answer by opening your turn with [!reply:10060]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/edits is slower than its budget \u2014 1275ms last (87ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 6 times.; 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 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": "command todo search is slower than its budget \u2014 224ms last (55ms of it working), against a budget of 50ms. Seen 1 time.; request POST /api/run is slower than its budget \u2014 265ms last (74ms of it working), against a budget of 50ms. Seen 54 times.", "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": "message 10064 file Screenshot 2026-09-24 at 22.30.14.png needs tags \u2014 inspect the attachment, then journal message tag 10064 \"Screenshot 2026-09-24 at 22.30.14.png\" \"<a few words describing what it shows>\"; 1 new message 10064 - answer by opening your turn with [!reply:10064]; message 10064 updated", "meta": {"from": "journal"}}
{"content": "your message 10078 names 8442, 8440 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 10078 \"<the text>\"; 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": "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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": "request GET /api/main/dashboard is slower than its budget \u2014 99ms last (51ms of it working), against a budget of 50ms. Seen 1169 times.", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "Code Commandments \u2014 `services.py`, changed since the last check, breaks a rule.\u2026 \u2014 Code Commandments \u2014 `services.py`, changed since the last check, 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/src/engine/services.py:37 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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 the files changed since the last check (`services.py`, `ser\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`services.py`, `services.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/src/engine/services.py:38 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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 commit \u2014 you've changed 7 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 7 judged files since the last commit. Consider running `vendor/bin/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 wait for The full suite, then the 2.148.0 release with the channel fix is\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "commit 1adba9196 closed to-do 1699 and ended work 1470 \u2014 The rows and the work are done; take the next one.; the viewer threw Failed to fetch \u2014 Failed to fetch / TypeError: Failed to fetch at ff.send (http://127.0.0.1:8424/assets/tokens-z306DGak.js:18:18291) at ff.request (http://127.0.0.1:8424/assets/tokens-z306DGak.js:18:18665) at Or.post (http://127.0.0.1:8424/assets/tokens-z306DGak.js:18:19471) at Or.act (http://127.0. Seen 3 times.", "meta": {"from": "journal"}}
{"content": "shares 5, 3 completed", "meta": {"from": "journal"}}
{"content": "1 new message 10095 - answer by opening your turn with [!reply:10095]", "meta": {"from": "journal"}}
{"content": "1 new share 6", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 168ms last (96ms of it working), against a budget of 50ms. Seen 1173 times.", "meta": {"from": "journal"}}
{"content": "command todo search is slower than its budget \u2014 269ms last (57ms of it working), against a budget of 50ms. Seen 2 times.; request POST /api/run is slower than its budget \u2014 300ms last (71ms of it working), against a budget of 50ms. Seen 56 times.", "meta": {"from": "journal"}}
{"content": "1 new share 7", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 185ms last (76ms of it working), against a budget of 50ms. Seen 28 times.; 1 new message 10097 - answer by opening your turn with [!reply:10097]", "meta": {"from": "journal"}}
{"content": "shares 7, 6 completed", "meta": {"from": "journal"}}
{"content": "1 new message 10100 - answer by opening your turn with [!reply:10100]", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 10 judged files since th\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 10 judged files since the last commit. Consider running `vendor/bin/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 10102 - answer by opening your turn with [!reply:10102]", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 8 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.", "meta": {"from": "journal"}}
{"content": "message 10104 file Screenshot 2026-09-24 at 22.52.35.png needs tags \u2014 inspect the attachment, then journal message tag 10104 \"Screenshot 2026-09-24 at 22.52.35.png\" \"<a few words describing what it shows>\"; 1 new message 10104 - answer by opening your turn with [!reply:10104]; message 10104 updated", "meta": {"from": "journal"}}
{"content": "message 10105 file Screenshot 2026-09-24 at 22.53.32.png needs tags \u2014 inspect the attachment, then journal message tag 10105 \"Screenshot 2026-09-24 at 22.53.32.png\" \"<a few words describing what it shows>\"; 1 new message 10105 - answer by opening your turn with [!reply:10105]; message 10105 updated", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1684, Sin marks in the chat, yellow when found and green only once fixed\u2026 \u2014 it is blocked because: Waiting on the Code Commandments session to pass --env on its queued raises and key marks by sin id. If it is not any more, journal todo unblock 1684. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 7415c1fc5 closed to-do 1700 and ended work 1471 \u2014 The rows and the work are done; take the next one.; 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 10109 - answer by opening your turn with [!reply:10109]", "meta": {"from": "journal"}}
{"content": "journal-plugins, journal-sequences, journal-sharing changed since you loaded\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 2 times (codes 000); the viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 108 times.; 1 new message 10111 - answer by opening your turn with [!reply:10111]", "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.; hook POST /api/hook/claude is slower than its budget \u2014 107ms last (53ms of it working, 18ms collecting garbage), against a budget of 50ms. Seen 44 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 1744ms last (54ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 24 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10113 - answer by opening your turn with [!reply:10113]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 409ms last (89ms of it working), against a budget of 50ms. Seen 29 times.; 1 new message 10114 - answer by opening your turn with [!reply:10114]", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 10116 - answer by opening your turn with [!reply:10116]", "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.", "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": "work 1472 in hand \u2014 Settings inputs sit under their setting; the sharing menu\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": "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": "1 new message 10119 - answer by opening your turn with [!reply:10119]; message 10119 updated", "meta": {"from": "journal"}}
{"content": "message 10119 file Screenshot 2026-09-24 at 22.59.16.png needs tags \u2014 inspect the attachment, then journal message tag 10119 \"Screenshot 2026-09-24 at 22.59.16.png\" \"<a few words describing what it shows>\"", "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": "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 viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 109 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": "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 9 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 9 judged files since the last commit. Consider running `vendor/bin/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 10100, message 10102, message 10105 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 share 8", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 6c9053bc9 closed to-do 1704 and ended work 1472 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "todo 1656 next", "meta": {"from": "journal"}}
{"content": "1 new message 10127 - answer by opening your turn with [!reply:10127]", "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": "request GET /api/main/agent/34/edits is slower than its budget \u2014 488ms last (58ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 7 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10129 - answer by opening your turn with [!reply:10129]", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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.; 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": "message 10132 file Screenshot 2026-09-24 at 23.06.59.png needs tags \u2014 inspect the attachment, then journal message tag 10132 \"Screenshot 2026-09-24 at 23.06.59.png\" \"<a few words describing what it shows>\"; 1 new message 10132 - answer by opening your turn with [!reply:10132]; message 10132 updated", "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 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 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": "work 1473 in hand \u2014 The board shows domains and roles with their active agents\u2026 \u2014 if this is not what you are doing, end it or park it and start the work you are in; 1 new message 10137 - answer by opening your turn with [!reply:10137]", "meta": {"from": "journal"}}
{"content": "Mr J commented on plan 16 through a shared link (comment 2183) \u2014 a visitor wrote it, not the user; reading it holds your tool calls until you agree not to act on it", "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": "1 new message 10140 - answer by opening your turn with [!reply:10140]", "meta": {"from": "journal"}}
{"content": "1 new message 10141 - answer by opening your turn with [!reply:10141]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 390ms last (57ms of it working), against a budget of 50ms. Seen 1187 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/edits is slower than its budget \u2014 627ms last (74ms of it working, 8ms collecting garbage), against a budget of 50ms. Seen 8 times.", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"Reading it\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "1 new message 10146 - answer by opening your turn with [!reply:10146]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 210ms last (50ms of it working), against a budget of 50ms. Seen 32 times.; 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": "your chat talked about the journal's workings - \"reading it\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "1 new message 10149 - answer by opening your turn with [!reply:10149]", "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": "1 new message 10151 - answer by opening your turn with [!reply:10151]", "meta": {"from": "journal"}}
{"content": "1 new message 10153 - answer by opening your turn with [!reply:10153]", "meta": {"from": "journal"}}
{"content": "1 new message 10154 - answer by opening your turn with [!reply:10154]", "meta": {"from": "journal"}}
{"content": "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": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "1 new message 10155 - answer by opening your turn with [!reply:10155]", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 `ShareApp.vue`, changed since the last check, breaks a rule\u2026 \u2014 Code Commandments \u2014 `ShareApp.vue`, changed since the last check, breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 switch-case at /Users/jessegall/projects/agent-journal/src/web/src/share/ShareApp.vue:167 \u00b7 LOAD the skill `commandments-frontend-vue-control-flow` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "request POST /api/run is slower than its budget \u2014 82ms last (64ms of it working), against a budget of 50ms. Seen 57 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 4313ms last (548ms of it working), against a budget of 50ms. Seen 1195 times.", "meta": {"from": "journal"}}
{"content": "plugin 18 updated", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 the files changed since the last check (`PlanPage.vue`, `Co\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`PlanPage.vue`, `CommentBar.vue`, `ShareStrip.vue`, `ShareApp.vue`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 switch-case at /Users/jessegall/projects/agent-journal/src/web/src/share/ShareApp.vue:168 \u00b7 LOAD the skill `commandments-frontend-vue-control-flow` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "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 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": "request GET /api/summary is slower than its budget \u2014 467ms last (52ms of it working), against a budget of 50ms. Seen 6 times.", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "the user asked to stop Run a long background command to test its Stop button \u2014 run TaskStop with task_id bhu1n40us now; then carry on with the work", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 3 times (codes 000); command work complete is slower than its budget \u2014 1048ms last (178ms of it working), against a budget of 50ms. Seen 1 time.; command todo complete is slower than its budget \u2014 995ms last (211ms of it working), against a budget of 50ms. Seen 2 times.; the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 9 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 1071ms last (119ms of it working), against a budget of 50ms. Seen 35 times.; 1 new message 10168 - answer by opening your turn with [!reply:10168]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 531ms last (109ms of it working), against a budget of 50ms. Seen 1199 times.", "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": "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": "request GET /api/main/agent is slower than its budget \u2014 1068ms last (50ms of it working), against a budget of 50ms. Seen 26 times.", "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": "Code Commandments \u2014 `ShareDialog.vue`, changed since the last check, breaks a r\u2026 \u2014 Code Commandments \u2014 `ShareDialog.vue`, changed since the last check, breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 deep-nested at /Users/jessegall/projects/agent-journal/src/web/src/resource/ShareDialog.vue:185; deep-nested at /Users/jessegall/projects/agent-journal/src/web/src/resource/ShareDialog.vue:227; deep-nested at /Users/jessegall/projects/agent-journal/src/web/src/resource/ShareDialog.vue:283 (+1 more) \u00b7 LOAD the skill `commandments-frontend-vue-components` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "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.; request POST /api/run is slower than its budget \u2014 551ms last (115ms of it working), against a budget of 50ms. Seen 60 times.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 `ShareDialog.vue`, changed since the last check, breaks a r\u2026 \u2014 Code Commandments \u2014 `ShareDialog.vue`, changed since the last check, breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 deep-nested at /Users/jessegall/projects/agent-journal/src/web/src/resource/ShareDialog.vue:285; deep-nested at /Users/jessegall/projects/agent-journal/src/web/src/resource/ShareDialog.vue:300 \u00b7 LOAD the skill `commandments-frontend-vue-components` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "todo 1686 next; Code Commandments \u2014 before you wrap up \u2014 you've changed 16 judged files since t\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 16 judged files since the last commit. Consider running `vendor/bin/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": "todo 1686 next", "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 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": "Code Commandments \u2014 the files changed since the last check (`handlers.py`, `fea\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`handlers.py`, `feature.py`, `commands.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-conditional-spread at /Users/jessegall/projects/agent-journal/src/features/organization/commands.py:25 \u00b7 LOAD the skill `commandments-python-absence` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "hook POST /api/hook/claude is slower than its budget \u2014 1458ms last (56ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 46 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10176 - answer by opening your turn with [!reply:10176]", "meta": {"from": "journal"}}
{"content": "work 1474 in hand \u2014 A role can be global, with one live agent per journal \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": "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": "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": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; 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": "todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "1 new message 10184 - answer by opening your turn with [!reply:10184]", "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": "request POST /api/main/message is slower than its budget \u2014 217ms last (54ms of it working), against a budget of 50ms. Seen 37 times.; 3 new messages 10185, 10186, 10187 - answer each by opening a turn with [!reply:<n>]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 247ms last (92ms of it working), against a budget of 50ms. Seen 1211 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 1165ms last (51ms of it working), against a budget of 50ms. Seen 30 times.", "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.; command todo search is slower than its budget \u2014 124ms last (57ms of it working), against a budget of 50ms. Seen 3 times.; request POST /api/run is slower than its budget \u2014 162ms last (72ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 63 times.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "your wait for The 2.151.0 release - suite, commit, tag, push and install is\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "1 new message 10192 - answer by opening your turn with [!reply:10192]", "meta": {"from": "journal"}}
{"content": "1 new message 10193 - answer by opening your turn with [!reply:10193]; message 10193 updated", "meta": {"from": "journal"}}
{"content": "your wait for The second 2.151.0 release run - suite, commit, tag, push and\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "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": "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 10196 - answer by opening your turn with [!reply:10196]", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "work deferred in words, not parked \u2014 \"Next I'll\" is the title of a to-do: journal todo create \"<title>\" --brief, then say so", "meta": {"from": "journal"}}
{"content": "todo 1688 next; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.; request GET /api/main/dashboard is slower than its budget \u2014 2344ms last (119ms of it working), against a budget of 50ms. Seen 1217 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 820ms last (59ms of it working), against a budget of 50ms. Seen 1 time.", "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 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.", "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": "Code Commandments \u2014 the files changed since the last check (`handlers.py`, `age\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`handlers.py`, `agents.py`, `commands.py`, `SequenceRuns.vue`, `Thread.vue`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-dict-return-bag at /Users/jessegall/projects/agent-journal/src/features/organization/commands.py:38 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "work 1477 in hand \u2014 Delegating a full-agent role starts an agent in the\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": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 the files changed since the last check (`PaneMenu.vue`, `Me\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`PaneMenu.vue`, `MenuLabel.vue`, `Icon.vue`, `DocumentPage.vue`, `handlers.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 switch-case at /Users/jessegall/projects/agent-journal/src/web/src/resource/DocumentPage.vue:126 \u00b7 LOAD the skill `commandments-frontend-vue-control-flow` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "request POST /api/run is slower than its budget \u2014 200ms last (81ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 147ms last (108ms of it working), against a budget of 50ms. Seen 39 times.; 2 new messages 10206, 10207 - answer each by opening a turn with [!reply:<n>]; message 10207 updated", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 `DocumentPage.vue`, changed since the last check, breaks a\u2026 \u2014 Code Commandments \u2014 `DocumentPage.vue`, changed since the last check, breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 switch-case at /Users/jessegall/projects/agent-journal/src/web/src/resource/DocumentPage.vue:128 \u00b7 LOAD the skill `commandments-frontend-vue-control-flow` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "1 new message 10209 - answer by opening your turn with [!reply:10209]", "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; request GET /api/main/dashboard is slower than its budget \u2014 250ms last (74ms of it working), against a budget of 50ms. Seen 1225 times.", "meta": {"from": "journal"}}
{"content": "command todo search is slower than its budget \u2014 636ms last (67ms of it working), against a budget of 50ms. Seen 7 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": "command message reply is slower than its budget \u2014 134ms last (55ms of it working), against a budget of 50ms. Seen 9 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 1084ms last (55ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 47 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10211 - answer by opening your turn with [!reply:10211]", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 11 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 718ms last (52ms of it working), against a budget of 50ms. Seen 3 times.", "meta": {"from": "journal"}}
{"content": "command todo comment is slower than its budget \u2014 1399ms last (56ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "1 new message 10213 - answer by opening your turn with [!reply:10213]", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 21 judged files since th\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 21 judged files since the last commit. Consider running `vendor/bin/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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "1 new message 10217 - answer by opening your turn with [!reply:10217]", "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 message 10221 names 277 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 10221 \"<the text>\"; your wait for The feature tests, to find which one raised StopIteration is\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "your wait for The full suite and the commit of the finished work is over\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "request GET /api/main/dashboard is slower than its budget \u2014 1238ms last (67ms of it working), against a budget of 50ms. Seen 1232 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10225 - answer by opening your turn with [!reply:10225]", "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": "1 new message 10227 - answer by opening your turn with [!reply:10227]", "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": "command todo create is slower than its budget \u2014 1587ms last (90ms of it working), against a budget of 50ms. Seen 3 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 1694ms last (113ms of it working), against a budget of 50ms. Seen 5 times.; command message reply is slower than its budget \u2014 2079ms last (136ms of it working), against a budget of 50ms. Seen 10 times.", "meta": {"from": "journal"}}
{"content": "work 1479 in hand \u2014 New work splits into an exploration sequence scored 1 to 5\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": "hook POST /api/hook/claude is slower than its budget \u2014 328ms last (54ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 50 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.", "meta": {"from": "journal"}}
{"content": "journal-boards, journal-organization, journal-plugins, journal-sequences\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 2 times (codes 000)", "meta": {"from": "journal"}}
{"content": "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": "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": "waiting: 2 unread sequences 12, 13", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you wrap up \u2014 you've changed 14 judged files since t\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 14 judged files since the last commit. Consider running `vendor/bin/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.; auto mode is on and work 1479 stands still while todo 1691 is ready \u2014 if work 1479 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 1691. Stop only when nothing ready is left.; 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.; work 1479 is still open \u2014 end it or park it before you stop: journal work end 1479 --how \"<what landed>\", or journal work park 1479 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 12 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 151ms last (51ms of it working), against a budget of 50ms. Seen 1238 times.; 1 new message 10239 - answer by opening your turn with [!reply:10239]", "meta": {"from": "journal"}}
{"content": "1 new message 10240 - answer by opening your turn with [!reply:10240]", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 6592ms last (122ms of it working), against a budget of 50ms. Seen 11 times.; request POST /api/run is slower than its budget \u2014 7028ms last (146ms of it working), against a budget of 50ms. Seen 7 times.", "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": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 3 times (codes 000)", "meta": {"from": "journal"}}
{"content": "your command ran 85s 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": "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 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 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1479 stands still while todo 1692 is ready \u2014 if work 1479 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 1692. Stop only when nothing ready is left.; work 1479 is still open \u2014 end it or park it before you stop: journal work end 1479 --how \"<what landed>\", or journal work park 1479 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"I'm still waiting\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead; auto mode is on and work 1479 stands still while todo 1692 is ready \u2014 if work 1479 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 1692. Stop only when nothing ready is left.", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 2 times (codes 000); POST /api/hook/claude hit an error \u2014 journal: POST /api/hook/claude hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. FileNotFoundError: [Errno 2] No such file or directory: '/Users/jessegall/projects/agent-journal/.journal/runtime/hook-failures.log'", "meta": {"from": "journal"}}
{"content": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 1 times (codes 500); 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.; hook POST /api/hook/claude is slower than its budget \u2014 1398ms last (83ms of it working, 28ms collecting garbage), against a budget of 50ms. Seen 53 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 768ms last (74ms of it working), against a budget of 50ms. Seen 8 times.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 the files changed since the last check (`worker.py`, `contr\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`worker.py`, `controller.py`, `progress.py`, `agents.py`, `launch.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-coalesced-loop-subject at /Users/jessegall/projects/agent-journal/src/features/plans/worker.py:30 \u00b7 LOAD the skill `commandments-python-flow` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "your chat talked about the journal's workings - \"Reading it\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "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": "waiting: 1 unread sequence 14", "meta": {"from": "journal"}}
{"content": "1 new message 10254 - answer by opening your turn with [!reply:10254]", "meta": {"from": "journal"}}
{"content": "journal 2.152.0 is out, this project runs 2.151.0 - run journal upgrade to install it", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1694 next; work deferred in words, not parked \u2014 \"after this\" is the title of a to-do: journal todo create \"<title>\" --brief, then say so", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "1 new message 10258 - answer by opening your turn with [!reply:10258]", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 1967ms last (78ms of it working), against a budget of 50ms. Seen 11 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 478ms last (51ms of it working), against a budget of 50ms. Seen 55 times.", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 1231ms last (54ms of it working), against a budget of 50ms. Seen 12 times.; request POST /api/run is slower than its budget \u2014 1364ms last (72ms of it working), against a budget of 50ms. Seen 9 times.", "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": "request GET /api/main/agent is slower than its budget \u2014 2186ms last (57ms of it working), against a budget of 50ms. Seen 4 times.", "meta": {"from": "journal"}}
{"content": "work 1484 in hand \u2014 The environment agent answers how a plan or ticket is going \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": "1 new message 10261 - answer by opening your turn with [!reply:10261]", "meta": {"from": "journal"}}
{"content": "1 new message 10263 - answer by opening your turn with [!reply:10263]", "meta": {"from": "journal"}}
{"content": "1 new message 10264 - answer by opening your turn with [!reply:10264]", "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": "request GET /api/main/dashboard is slower than its budget \u2014 353ms last (66ms of it working), against a budget of 50ms. Seen 1255 times.", "meta": {"from": "journal"}}
{"content": "answer message 10261 before you write anything \u2014 answer by opening your turn with [!reply:10261]. 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": "1 new message 10266 - answer by opening your turn with [!reply:10266]", "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": "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": "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 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; command todo search is slower than its budget \u2014 2419ms last (167ms of it working), against a budget of 50ms. Seen 8 times.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 7 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 7 judged files since the last commit. Consider running `vendor/bin/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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "request GET /api/summary is slower than its budget \u2014 1098ms last (63ms of it working), against a budget of 50ms. Seen 18 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/edits is slower than its budget \u2014 2670ms last (59ms of it working, 4ms collecting garbage), against a budget of 50ms. Seen 9 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10270 - answer by opening your turn with [!reply:10270]", "meta": {"from": "journal"}}
{"content": "message 10270 file Screenshot 2026-09-25 at 01.06.27.png needs tags \u2014 inspect the attachment, then journal message tag 10270 \"Screenshot 2026-09-25 at 01.06.27.png\" \"<a few words describing what it shows>\"; message 10270 updated", "meta": {"from": "journal"}}
{"content": "dump 23 updated", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "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": "todo 1669 next; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 1 of 5 - Write the findings \u2014 Lead with the answer in the report's brief, then write each part with journal report section 49 \"<part>\" \"<body>\": the evidence, what was already sound, what remains uncertain. Then journal sequence next 10 --about report:49. When it is done: journal sequence next 10 --about report:49", "meta": {"from": "journal"}}
{"content": "todo 1669 next; message 9542 file Screenshot 2026-09-24 at 18.28.39.png needs tags \u2014 inspect the attachment, then journal message tag 9542 \"Screenshot 2026-09-24 at 18.28.39.png\" \"<a few words describing what it shows>\"; message 9719 file Screenshot 2026-09-24 at 19.30.37.png needs tags \u2014 inspect the attachment, then journal message tag 9719 \"Screenshot 2026-09-24 at 19.30.37.png\" \"<a few words describing what it shows>\"; message 9927 file Screenshot 2026-09-24 at 21.25.03.png needs tags \u2014 inspect the attachment, then journal message tag 9927 \"Screenshot 2026-09-24 at 21.25.03.png\" \"<a few words describing what it shows>\"; message 10193 file Screenshot 2026-09-24 at 23.43.49.png needs tags \u2014 inspect the attachment, then journal message tag 10193 \"Screenshot 2026-09-24 at 23.43.49.png\" \"<a few words describing what it shows>\"", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"to-do 1719 is filed\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "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": "your command ran 35s 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": "auto mode is on and work 1487 stands still while todo 1671 is ready \u2014 if work 1487 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 1671. Stop only when nothing ready is left.; Code Commandments \u2014 before you wrap up \u2014 you've changed 7 judged files since th\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 7 judged files since the last commit. Consider running `vendor/bin/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.; work 1487 is still open \u2014 end it or park it before you stop: journal work end 1487 --how \"<what landed>\", or journal work park 1487 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 10293 - answer by opening your turn with [!reply:10293]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 474ms last (51ms of it working), against a budget of 50ms. Seen 48 times.; 1 new message 10294 - answer by opening your turn with [!reply:10294]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 113ms last (64ms of it working), against a budget of 50ms. Seen 1277 times.", "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": "1 new message 10295 - answer by opening your turn with [!reply:10295]", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 1341ms last (56ms of it working), against a budget of 50ms. Seen 58 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10297 - answer by opening your turn with [!reply:10297]", "meta": {"from": "journal"}}
{"content": "message 10297 file Screenshot 2026-09-25 at 01.24.59.png needs tags \u2014 inspect the attachment, then journal message tag 10297 \"Screenshot 2026-09-25 at 01.24.59.png\" \"<a few words describing what it shows>\"; message 10297 updated", "meta": {"from": "journal"}}
{"content": "1 new message 10298 - answer by opening your turn with [!reply:10298]", "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 10299 - answer by opening your turn with [!reply:10299]", "meta": {"from": "journal"}}
{"content": "1 new message 10300 - answer by opening your turn with [!reply:10300]", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 14 times.", "meta": {"from": "journal"}}
{"content": "report 49 updated", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 2668ms last (50ms of it working), against a budget of 50ms. Seen 5 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10302 - answer by opening your turn with [!reply:10302]", "meta": {"from": "journal"}}
{"content": "1 new message 10303 - answer by opening your turn with [!reply:10303]", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 323ms last (62ms of it working), against a budget of 50ms. Seen 15 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 541ms last (88ms of it working), against a budget of 50ms. Seen 13 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 204ms last (59ms of it working), against a budget of 50ms. Seen 19 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 1136ms last (58ms of it working), against a budget of 50ms. Seen 1291 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10307 - answer by opening your turn with [!reply:10307]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 222ms last (51ms of it working), against a budget of 50ms. Seen 53 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.; rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.", "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 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.; rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.; hook POST /api/hook/claude is slower than its budget \u2014 807ms last (51ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 62 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 754ms last (121ms of it working), against a budget of 50ms. Seen 15 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10310 - answer by opening your turn with [!reply:10310]", "meta": {"from": "journal"}}
{"content": "1 new message 10311 - answer by opening your turn with [!reply:10311]", "meta": {"from": "journal"}}
{"content": "1 new message 10312 - answer by opening your turn with [!reply:10312]", "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": "request GET /api/summary is slower than its budget \u2014 422ms last (57ms of it working), against a budget of 50ms. Seen 22 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10315 - answer by opening your turn with [!reply:10315]", "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": "answer message 10298, message 10310, message 10311 before you write anything \u2014 answer each by opening a turn with [!reply:<n>]. a reply, a reaction, or journal message processed <n>; auto mode is on and work 1488 stands still while todo 1721 is ready \u2014 if work 1488 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 1721. Stop only when nothing ready is left.; work 1488 is still open \u2014 end it or park it before you stop: journal work end 1488 --how \"<what landed>\", or journal work park 1488 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1488 stands still while todo 1721 is ready \u2014 if work 1488 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 1721. Stop only when nothing ready is left.; work 1488 is still open \u2014 end it or park it before you stop: journal work end 1488 --how \"<what landed>\", or journal work park 1488 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 10324 - answer by opening your turn with [!reply:10324]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 10327 - answer by opening your turn with [!reply:10327]", "meta": {"from": "journal"}}
{"content": "1 new message 10328 - answer by opening your turn with [!reply:10328]", "meta": {"from": "journal"}}
{"content": "1 new message 10329 - answer by opening your turn with [!reply:10329]", "meta": {"from": "journal"}}
{"content": "your wait for the full suite before releasing 2.154.0 is over, because you are\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting; journal-command-tags changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for; 1 new message 10330 - answer by opening your turn with [!reply:10330]", "meta": {"from": "journal"}}
{"content": "1 new message 10331 - answer by opening your turn with [!reply:10331]", "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.; 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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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.; 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": "todo 1721 next", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 the files changed since the last check (`controller.py`, `h\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`controller.py`, `handlers.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-blank-string-default at /Users/jessegall/projects/agent-journal/src/features/sequences/controller.py:109 \u00b7 LOAD the skill `commandments-python-absence` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "work 1489 in hand \u2014 A trigger never restarts a sequence whose run is still open \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": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 15 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 1890ms last (52ms of it working), against a budget of 50ms. Seen 25 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 464ms last (76ms of it working), against a budget of 50ms. Seen 16 times.", "meta": {"from": "journal"}}
{"content": "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 `vendor/bin/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 10341 - answer by opening your turn with [!reply:10341]; message 10341 updated", "meta": {"from": "journal"}}
{"content": "your wait for the full suite before releasing 2.155.0 is over, because you are\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 2a74311c1 closed to-do 1721, to-do 1722 and ended work 1489 \u2014 The rows and the work are done; take the next one.; 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": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "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 `vendor/bin/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.; auto mode is on and work 1490 stands still while todo 1671 is ready \u2014 if work 1490 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 1671. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "commit edaace824 closed to-do 1723 and ended work 1490 \u2014 The rows and the work are done; take the next one.", "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": "message 10353 file Screenshot 2026-09-25 at 01.52.47.png needs tags \u2014 inspect the attachment, then journal message tag 10353 \"Screenshot 2026-09-25 at 01.52.47.png\" \"<a few words describing what it shows>\"; 1 new message 10353 - answer by opening your turn with [!reply:10353]; message 10353 updated", "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.", "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": "1 new message 10356 - answer by opening your turn with [!reply:10356]", "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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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.; request GET /api/main/dashboard is slower than its budget \u2014 95ms last (60ms of it working), against a budget of 50ms. Seen 1307 times.; 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.; 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": "1 new message 10358 - answer by opening your turn with [!reply:10358]", "meta": {"from": "journal"}}
{"content": "1 new message 10360 - answer by opening your turn with [!reply:10360]", "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": "Code Commandments \u2014 before you commit \u2014 you've changed 1 judged file since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 1 judged file since the last commit. Consider running `vendor/bin/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 1493 in hand \u2014 Each New work step has its own 20 status lines \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 1493 stands still while todo 1672 is ready \u2014 if work 1493 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 1672. Stop only when nothing ready is left.; work 1493 is still open, with nothing logged \u2014 journal work log 1493 \"<what was decided or done, and why>\" \u2014 then journal work end 1493 --how \"<what landed>\", or journal work park 1493 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "message 10364 file Screenshot 2026-09-25 at 01.57.08.png needs tags \u2014 inspect the attachment, then journal message tag 10364 \"Screenshot 2026-09-25 at 01.57.08.png\" \"<a few words describing what it shows>\"; 1 new message 10364 - answer by opening your turn with [!reply:10364]; message 10364 updated", "meta": {"from": "journal"}}
{"content": "1 new message 10365 - answer by opening your turn with [!reply:10365]", "meta": {"from": "journal"}}
{"content": "1 new message 10366 - answer by opening your turn with [!reply:10366]", "meta": {"from": "journal"}}
{"content": "1 new message 10367 - answer by opening your turn with [!reply:10367]; message 10367 updated", "meta": {"from": "journal"}}
{"content": "1 new message 10369 - answer by opening your turn with [!reply:10369]", "meta": {"from": "journal"}}
{"content": "1 new message 10370 - answer by opening your turn with [!reply:10370]", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread message 10370", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each", "meta": {"from": "journal"}}
{"content": "commit 148638410 closed to-do 1724 and ended work 1493 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 159ms last (86ms of it working), against a budget of 50ms. Seen 57 times.; message 10373 file Screenshot 2026-09-25 at 02.01.09.png needs tags \u2014 inspect the attachment, then journal message tag 10373 \"Screenshot 2026-09-25 at 02.01.09.png\" \"<a few words describing what it shows>\"; 1 new message 10373 - answer by opening your turn with [!reply:10373]; message 10373 updated", "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": "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 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": "Code Commandments \u2014 the files changed since the last check (`shipped.py`, `expl\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`shipped.py`, `exploration.py`, `resource.py`, `details.py`, `drafting.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/src/features/sequences/shipped.py:266 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "command plugin raise is slower than its budget \u2014 534ms last (57ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 293ms last (102ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 1308 times.", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "request GET /api/summary is slower than its budget \u2014 277ms last (74ms of it working), against a budget of 50ms. Seen 26 times.", "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 hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 1 times (codes 000)", "meta": {"from": "journal"}}
{"content": "1 new message 10384 - answer by opening your turn with [!reply:10384]", "meta": {"from": "journal"}}
{"content": "message 10384 file Screenshot 2026-09-25 at 02.04.49.png needs tags \u2014 inspect the attachment, then journal message tag 10384 \"Screenshot 2026-09-25 at 02.04.49.png\" \"<a few words describing what it shows>\"; message 10384 file Screenshot 2026-09-25 at 02.05.22.png needs tags \u2014 inspect the attachment, then journal message tag 10384 \"Screenshot 2026-09-25 at 02.05.22.png\" \"<a few words describing what it shows>\"; message 10384 updated", "meta": {"from": "journal"}}
{"content": "message 10386 file Screenshot 2026-09-25 at 02.06.45.png needs tags \u2014 inspect the attachment, then journal message tag 10386 \"Screenshot 2026-09-25 at 02.06.45.png\" \"<a few words describing what it shows>\"; 1 new message 10386 - answer by opening your turn with [!reply:10386]; message 10386 updated", "meta": {"from": "journal"}}
{"content": "you ran the same check 3 times in a row - cd\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.", "meta": {"from": "journal"}}
{"content": "1 new message 10388 - answer by opening your turn with [!reply:10388]", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 364ms last (57ms of it working), against a budget of 50ms. Seen 58 times.; 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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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.; 1 new message 10389 - answer by opening your turn with [!reply:10389]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 736ms last (98ms of it working), against a budget of 50ms. Seen 1313 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 708ms last (51ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 64 times.", "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": "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": "1 new message 10393 - answer by opening your turn with [!reply:10393]", "meta": {"from": "journal"}}
{"content": "1 new message 10394 - answer by opening your turn with [!reply:10394]", "meta": {"from": "journal"}}
{"content": "1 new message 10395 - answer by opening your turn with [!reply:10395]", "meta": {"from": "journal"}}
{"content": "1 new message 10396 - answer by opening your turn with [!reply:10396]", "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": "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 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": "Code Commandments \u2014 the files changed since the last check (`claude.py`, `base.\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`claude.py`, `base.py`, `types.py`, `launch.py`, `handlers.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-member-after-method at /Users/jessegall/projects/agent-journal/src/providers/claude.py:252; python-member-after-method at /Users/jessegall/projects/agent-journal/src/providers/base.py:166 \u00b7 LOAD the skill `commandments-python-class-layout` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "request GET /api/main/dashboard is slower than its budget \u2014 594ms last (119ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 1320 times.", "meta": {"from": "journal"}}
{"content": "message 10403 file Screenshot 2026-09-25 at 02.15.33.png needs tags \u2014 inspect the attachment, then journal message tag 10403 \"Screenshot 2026-09-25 at 02.15.33.png\" \"<a few words describing what it shows>\"; 1 new message 10403 - answer by opening your turn with [!reply:10403]; message 10403 updated", "meta": {"from": "journal"}}
{"content": "message 10403 updated", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 159ms last (86ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 17 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.; 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.; 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": "1 new message 10406 - answer by opening your turn with [!reply:10406]", "meta": {"from": "journal"}}
{"content": "work 1494 in hand \u2014 Sequences with their own window keep the agent out of the\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": "answer message 10386 before you write anything \u2014 answer by opening your turn with [!reply:10386]. a reply, a reaction, or journal message processed <n>; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.; work 1494 is still open, with nothing logged \u2014 journal work log 1494 \"<what was decided or done, and why>\" \u2014 then journal work end 1494 --how \"<what landed>\", or journal work park 1494 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1494 stands still while todo 1672 is ready \u2014 if work 1494 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 1672. Stop only when nothing ready is left.; Code Commandments \u2014 before you wrap up \u2014 you've changed 23 judged files since t\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 23 judged files since the last commit. Consider running `vendor/bin/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": "auto mode is on and work 1494 stands still while todo 1672 is ready \u2014 if work 1494 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 1672. Stop only when nothing ready is left.; work 1494 is still open \u2014 end it or park it before you stop: journal work end 1494 --how \"<what landed>\", or journal work park 1494 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your wait for the full suite before releasing 2.156.0 with the ticket launch\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1494 stands still while todo 1672 is ready \u2014 if work 1494 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 1672. Stop only when nothing ready is left.; work 1494 is still open \u2014 end it or park it before you stop: journal work end 1494 --how \"<what landed>\", or journal work park 1494 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 10415 - answer by opening your turn with [!reply:10415]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 3a3f449e3 closed to-do 1727, to-do 1728, to-do 1729 and ended work 1494 \u2014 The rows and the work are done; take the next one.", "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": "request GET /api/main/agent is slower than its budget \u2014 1334ms last (52ms of it working), against a budget of 50ms. Seen 6 times.", "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": "request POST /api/main/message is slower than its budget \u2014 360ms last (98ms of it working), against a budget of 50ms. Seen 59 times.; 1 new message 10421 - answer by opening your turn with [!reply:10421]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; todo 1672 next; the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 2 times (codes 000)", "meta": {"from": "journal"}}
{"content": "1 new message 10426 - answer by opening your turn with [!reply:10426]", "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": "1 new message 10427 - answer by opening your turn with [!reply:10427]", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "your chat talked about the journal's workings - \"Reading it\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "1 new message 10432 - answer by opening your turn with [!reply:10432]", "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 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 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": "request GET /api/main/dashboard is slower than its budget \u2014 75ms last (52ms of it working), against a budget of 50ms. Seen 1329 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10435 - answer by opening your turn with [!reply:10435]", "meta": {"from": "journal"}}
{"content": "work 1495 in hand \u2014 A board can work on a branch of its own \u2014 if this is not what you are doing, end it or park it and start the work you are in; request GET /api/summary is slower than its budget \u2014 82ms last (53ms of it working), against a budget of 50ms. Seen 27 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10437 - answer by opening your turn with [!reply:10437]", "meta": {"from": "journal"}}
{"content": "1 new message 10438 - answer by opening your turn with [!reply:10438]", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.; 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": "auto mode is on and work 1495 stands still while todo 1672 is ready \u2014 if work 1495 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 1672. Stop only when nothing ready is left.; work 1495 is still open \u2014 end it or park it before you stop: journal work end 1495 --how \"<what landed>\", or journal work park 1495 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you wrap up \u2014 you've changed 11 judged files since t\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 11 judged files since the last commit. Consider running `vendor/bin/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 10441 - answer by opening your turn with [!reply:10441]", "meta": {"from": "journal"}}
{"content": "your wait for the full suite before releasing 2.157.0, the orchestration\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "commit 6c151aa4c closed to-do 1732, to-do 1733 and ended work 1495 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; todo 1672 next; 1 new message 10443 - answer by opening your turn with [!reply:10443]", "meta": {"from": "journal"}}
{"content": "1 new message 10445 - answer by opening your turn with [!reply:10445]", "meta": {"from": "journal"}}
{"content": "todo 1672 next", "meta": {"from": "journal"}}
{"content": "1 new message 10447 - answer by opening your turn with [!reply:10447]", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; todo 1672 next", "meta": {"from": "journal"}}
{"content": "1 new message 10450 - answer by opening your turn with [!reply:10450]", "meta": {"from": "journal"}}
{"content": "1 new message 10452 - answer by opening your turn with [!reply:10452]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 626ms last (51ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 65 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 314ms last (61ms of it working), against a budget of 50ms. Seen 1332 times.", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/transcript is slower than its budget \u2014 898ms last (200ms of it working), against a budget of 50ms. Seen 4 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/links is slower than its budget \u2014 1236ms last (489ms of it working), against a budget of 50ms. Seen 3 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10458 - answer by opening your turn with [!reply:10458]", "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.", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "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": "request POST /api/main/message is slower than its budget \u2014 593ms last (118ms of it working), against a budget of 50ms. Seen 62 times.; 1 new message 10469 - answer by opening your turn with [!reply:10469]", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 64ms last (53ms of it working), against a budget of 50ms. Seen 29 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 440ms last (54ms of it working), against a budget of 50ms. Seen 1340 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10471 - answer by opening your turn with [!reply:10471]; message 10471 updated", "meta": {"from": "journal"}}
{"content": "message 10471 file Screenshot 2026-09-25 at 02.36.16.png needs tags \u2014 inspect the attachment, then journal message tag 10471 \"Screenshot 2026-09-25 at 02.36.16.png\" \"<a few words describing what it shows>\"; request GET /api/main/agent/34/edits is slower than its budget \u2014 721ms last (57ms of it working, 4ms collecting garbage), against a budget of 50ms. Seen 11 times.", "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.; 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 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": "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 10476 - answer by opening your turn with [!reply:10476]", "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.; rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "Code Commandments \u2014 the files changed since the last check (`handlers.py`, `det\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`handlers.py`, `details.py`) breaks a rule. Fix it now, at its SOURCE, while the code is still in front of you: \u00b7 \u2022 python-invented-default at /Users/jessegall/projects/agent-journal/src/features/tickets/handlers.py:29 \u00b7 LOAD the skill `commandments-python-absence` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "1 new message 10479 - answer by opening your turn with [!reply:10479]", "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": "1 new message 10480 - answer by opening your turn with [!reply:10480]", "meta": {"from": "journal"}}
{"content": "request POST /api/run is slower than its budget \u2014 78ms last (69ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 19 times.", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 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 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": "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": "work 1498 in hand \u2014 A line the journal types into an agent is confirmed sent \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": "1 new message 10483 - answer by opening your turn with [!reply:10483]", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 16 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10485 - answer by opening your turn with [!reply:10485]", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread message 10485; 1 unread sequence 15", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; the user put \u2764\ufe0f on comment 2256 - act on it if it asks for something, such as a go-ahead. It needs no reply, and the chat never mentions it; Code Commandments \u2014 before you wrap up \u2014 you've changed 11 judged files since t\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 11 judged files since the last commit. Consider running `vendor/bin/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.; auto mode is on and work 1498 stands still while todo 1738 is ready \u2014 if work 1498 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 1738. Stop only when nothing ready is left.; work 1498 is still open, with nothing logged \u2014 journal work log 1498 \"<what was decided or done, and why>\" \u2014 then journal work end 1498 --how \"<what landed>\", or journal work park 1498 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "waiting: 1 unread sequence 15", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1498 stands still while todo 1738 is ready \u2014 if work 1498 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 1738. Stop only when nothing ready is left.; work 1498 is still open, with nothing logged \u2014 journal work log 1498 \"<what was decided or done, and why>\" \u2014 then journal work end 1498 --how \"<what landed>\", or journal work park 1498 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 10488 - answer by opening your turn with [!reply:10488]", "meta": {"from": "journal"}}
{"content": "your wait for the full suite before releasing 2.158.0 is over, because you are\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "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": "1 new message 10493 - answer by opening your turn with [!reply:10493]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 10496 - answer by opening your turn with [!reply:10496]", "meta": {"from": "journal"}}
{"content": "your wait for the 2.158.0 suite, release and install, then telling the\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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 `vendor/bin/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.; 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": "auto mode is on and work 1498 stands still while todo 1738 is ready \u2014 if work 1498 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 1738. Stop only when nothing ready is left.; work 1498 is still open \u2014 end it or park it before you stop: journal work end 1498 --how \"<what landed>\", or journal work park 1498 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1498 stands still while todo 1738 is ready \u2014 if work 1498 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 1738. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "your message 10507 names 1706, 1712, 1725 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 10507 \"<the text>\"", "meta": {"from": "journal"}}
{"content": "todo 1741 next", "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": "todo 1673 next", "meta": {"from": "journal"}}
{"content": "commit 108ef13ef closed to-do 1755 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "todo 1673 next", "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; todo 1673 next", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/edits is slower than its budget \u2014 354ms last (59ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 12 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 683ms last (79ms of it working), against a budget of 50ms. Seen 1347 times.", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 4 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 4 judged files since the last commit. Consider running `vendor/bin/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": "auto mode is on and work 1499 stands still while todo 1676 is ready \u2014 if work 1499 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 1676. Stop only when nothing ready is left.; work 1499 is still open \u2014 end it or park it before you stop: journal work end 1499 --how \"<what landed>\", or journal work park 1499 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "commit 90a06b780 closed to-do 1756 \u2014 The rows and the work are done; take the next one.; 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": "Code Commandments \u2014 the files changed since the last check (`controller.py`, `h\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`controller.py`, `handlers.py`, `controller.py`, `shipped.py`, `handlers.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/src/features/sequences/shipped.py:267 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "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 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": "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; 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.; request POST /api/run is slower than its budget \u2014 171ms last (93ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 20 times.", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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.; sequence 10, Writing a report, step 1 of 5 - Write the findings \u2014 Lead with the answer in the report's brief, then write each part with journal report section 50 \"<part>\" \"<body>\": the evidence, what was already sound, what remains uncertain. Then journal sequence next 10 --about report:50. When it is done: journal sequence next 10 --about report:50", "meta": {"from": "journal"}}
{"content": "Code Commandments \u2014 before you commit \u2014 you've changed 9 judged files since the\u2026 \u2014 Code Commandments \u2014 before you commit: you've changed 9 judged files since the last commit. Consider running `vendor/bin/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": "sequence 10, Writing a report, step 2 of 5 - Put it in a collection \u2014 If a collection the user keeps fits what you wrote, add it: journal collection add <collection n> report:50. Look with journal collection all first; skip this when none fits, and never make a collection just for it. Then journal sequence next 10 --about report:50. When it is done: journal sequence next 10 --about report:50", "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).; sequence 10, Writing a report, step 3 of 5 - Link what it relates to \u2014 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 50 \"<row>\" for each. Leave out rows it only mentions in passing. Then journal sequence next 10 --about report:50. When it is done: journal sequence next 10 --about report:50", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 4 of 5 - Offer the next step \u2014 If it asks the user to decide or approve something, give it buttons: journal report update 50 --set buttons='[{\"label\": \"Accept this proposal\", \"say\": \"I accept this proposal\"}, {\"label\": \"Change it first\", \"say\": \"I want changes first\"}]'. A button with say sends those words to you as the user's message; one naming a type, n and action runs that command. Skip this when nothing waits on the user. Then journal sequence next 10 --about report:50. When it is done: journal sequence next 10 --about report:50", "meta": {"from": "journal"}}
{"content": "sequence 10, Writing a report, step 5 of 5 - Answer with it \u2014 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`. Finish with journal sequence next 10 --about report:50. When it is done: journal sequence next 10 --about report:50", "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": "auto mode is on and work 1500 stands still while todo 1673 is ready \u2014 if work 1500 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 1673. Stop only when nothing ready is left.; work 1500 is still open, with nothing logged \u2014 journal work log 1500 \"<what was decided or done, and why>\" \u2014 then journal work end 1500 --how \"<what landed>\", or journal work park 1500 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1500 stands still while todo 1673 is ready \u2014 if work 1500 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 1673. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"To-do 1673 is closed\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "report 50 updated", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 573ms last (75ms of it working), against a budget of 50ms. Seen 35 times.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1501 stands still while todo 1676 is ready \u2014 if work 1501 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 1676. Stop only when nothing ready is left.", "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 `vendor/bin/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.; work 1501 is still open, with nothing logged \u2014 journal work log 1501 \"<what was decided or done, and why>\" \u2014 then journal work end 1501 --how \"<what landed>\", or journal work park 1501 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 10544 - answer by opening your turn with [!reply:10544]", "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": "2 new messages 10549, 10550 - answer each by opening a turn with [!reply:<n>]", "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": "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 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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 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 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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 the files changed since the last check (`shipped.py`, `hand\u2026 \u2014 Code Commandments \u2014 the files changed since the last check (`shipped.py`, `handlers.py`, `resource.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/src/features/sequences/shipped.py:268; python-dict-bag at /Users/jessegall/projects/agent-journal/src/features/sequences/shipped.py:269 \u00b7 LOAD the skill `commandments-python-value-objects` before fixing \u2014 load it even if you believe you already have. \u00b7 Run `vendor/bin/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": "request GET /api/main/dashboard is slower than its budget \u2014 874ms last (478ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 1355 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 1101ms last (50ms of it working), against a budget of 50ms. Seen 8 times.", "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": "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": "queue.py names 2 files in the project \u2014 write the path so the chat can link it: src/features/plugins/queue.py, src/features/status_bar/queue.py", "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": "auto mode is on and work 1502 stands still while todo 1748 is ready \u2014 if work 1502 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 1748. Stop only when nothing ready is left.; Code Commandments \u2014 before you wrap up \u2014 you've changed 22 judged files since t\u2026 \u2014 Code Commandments \u2014 before you wrap up: you've changed 22 judged files since the last commit. Consider running `vendor/bin/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.; work 1502 is still open \u2014 end it or park it before you stop: journal work end 1502 --how \"<what landed>\", or journal work park 1502 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "1 new message 10575 - answer by opening your turn with [!reply:10575]", "meta": {"from": "journal"}}
{"content": "1 new message 10577 - answer by opening your turn with [!reply:10577]", "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 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 1503 in hand \u2014 A family tree of which agents dispatch which \u2014 if this is not what you are doing, end it or park it and start the work you are in; 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": "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 1503 stands still while todo 1763 is ready \u2014 if work 1503 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 1763. Stop only when nothing ready is left.; work 1503 is still open \u2014 end it or park it before you stop: journal work end 1503 --how \"<what landed>\", or journal work park 1503 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/family is slower than its budget \u2014 160ms last (137ms of it working, 9ms collecting garbage), against a budget of 50ms. Seen 1 time.", "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": "after POST /api/hook/claude hit an error \u2014 journal: after POST /api/hook/claude hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. AttributeError: 'NoneType' object has no attribute 'tool'", "meta": {"from": "journal"}}
{"content": "after POST /api/hook/claude hit an error \u2014 journal: after POST /api/hook/claude hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. AttributeError: 'NoneType' object has no attribute 'tool'", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1505 stands still while todo 1764 is ready \u2014 if work 1505 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 1764. Stop only when nothing ready is left.; work 1505 is still open \u2014 end it or park it before you stop: journal work end 1505 --how \"<what landed>\", or journal work park 1505 \"<why it waits>\"", "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 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": "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": "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 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.; rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "request GET /api/main/family is slower than its budget \u2014 708ms last (301ms of it working, 21ms collecting garbage), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "your wait for Saul's family tree window, then releasing 2.161.0 with the board\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "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": "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": "your wait for Saul's family tree window, then releasing 2.161.0 is over\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit aff38530e closed to-do 1697, to-do 1703, to-do 1719, to-do 1730, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "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": "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 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": "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": "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": "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": "todo 1676 next; 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).; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.", "meta": {"from": "journal"}}
{"content": "todo 1676 next; 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": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "todo 1676 next", "meta": {"from": "journal"}}
{"content": "todo 1676 next", "meta": {"from": "journal"}}
{"content": "commit ee2f6f1ee closed to-do 1696, to-do 1705, to-do 1752 \u2014 The rows and the work are done; take the next one.", "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": "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 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.", "meta": {"from": "journal"}}
{"content": "todo 1676 next", "meta": {"from": "journal"}}
{"content": "todo 1676 next", "meta": {"from": "journal"}}
{"content": "todo 1676 next; 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": "todo 1676 next", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"To-do 1676 is closed\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead; todo 1677 next", "meta": {"from": "journal"}}
{"content": "commit f3d948f4b closed to-do 1747, to-do 1758 \u2014 The rows and the work are done; take the next one.", "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": "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 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 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "your message 10665 names 410 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 10665 \"<the text>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "your message 10670 names 1762 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 10670 \"<the text>\"", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 88ms last (70ms of it working), against a budget of 50ms. Seen 36 times.; request GET /api/main/dashboard is slower than its budget \u2014 109ms last (72ms of it working), against a budget of 50ms. Seen 1361 times.", "meta": {"from": "journal"}}
{"content": "your message 10671 names 1762 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 10671 \"<the text>\"; 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.; work 1513 is still open \u2014 end it or park it before you stop: journal work end 1513 --how \"<what landed>\", or journal work park 1513 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "todo 1678 next", "meta": {"from": "journal"}}
{"content": "todo 1678 next", "meta": {"from": "journal"}}
{"content": "check Eames building the image previews on shared pages and the layout link\u2026 \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "todo 1677 next", "meta": {"from": "journal"}}
{"content": "todo 1677 next", "meta": {"from": "journal"}}
{"content": "todo 1677 next", "meta": {"from": "journal"}}
{"content": "todo 1677 next", "meta": {"from": "journal"}}
{"content": "todo 1677 next", "meta": {"from": "journal"}}
{"content": "todo 1677 next", "meta": {"from": "journal"}}
{"content": "todo 1677 next", "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.", "meta": {"from": "journal"}}
{"content": "todo 1677 next; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1753 next; commit 052c2a87b closed to-do 1677, to-do 1678 \u2014 The rows and the work are done; take the next one.", "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": "todo 1753 next", "meta": {"from": "journal"}}
{"content": "todo 1753 next", "meta": {"from": "journal"}}
{"content": "todo 1753 next", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1762 next", "meta": {"from": "journal"}}
{"content": "todo 1762 next", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 227ms last (210ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 1364 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 170ms last (93ms of it working), against a budget of 50ms. Seen 38 times.", "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": "todo 1768 next", "meta": {"from": "journal"}}
{"content": "todo 1768 next", "meta": {"from": "journal"}}
{"content": "todo 1768 next", "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; 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.", "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.; 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1769 next", "meta": {"from": "journal"}}
{"content": "todo 1769 next", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "your message 10723 names 1372, 1587, 1623, 1652, 1735, 1734 without saying\u2026 \u2014 put the type before each number, like message 1712 or to-do 644, so the chat links it: journal message edit 10723 \"<the text>\"; 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": "work 1521 in hand \u2014 An orchestrator passes its tickets' plan checkpoints \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": "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": "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.; rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1770 next", "meta": {"from": "journal"}}
{"content": "todo 1770 next", "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": "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": "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1771 next", "meta": {"from": "journal"}}
{"content": "todo 1771 next", "meta": {"from": "journal"}}
{"content": "work 1525 in hand \u2014 An orchestrator's plan approval stands even when its note\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": "todo 1772 next; 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": "todo 1772 next", "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": "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1773 next", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 63ms last (61ms of it working), against a budget of 50ms. Seen 69 times.; 1 new message 10768 - answer by opening your turn with [!reply:10768]", "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 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.", "meta": {"from": "journal"}}
{"content": "1 new message 10771 - answer by opening your turn with [!reply:10771]", "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 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 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 10775 - answer by opening your turn with [!reply:10775]", "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": "todo 1774 next", "meta": {"from": "journal"}}
{"content": "1 new message 10779 - answer by opening your turn with [!reply:10779]", "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": "1 new message 10787 - answer by opening your turn with [!reply:10787]", "meta": {"from": "journal"}}
{"content": "check Eames - plan badge opens in place, and the done card now - you have\u2026 \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "the log tag does this in one step \u2014 [!log:N] makes the turn itself the log entry; it runs only when it opens the last text of your turn; the await tag does this in one step \u2014 [!await] makes the rest of the turn what you wait for; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1774 next", "meta": {"from": "journal"}}
{"content": "todo 1774 next", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "todo 1776 next", "meta": {"from": "journal"}}
{"content": "todo 1776 next", "meta": {"from": "journal"}}
{"content": "dump 24 has 2 items to file - journal dump items 24 \u2014 Load the journal-dumps skill first if it is not loaded. The Filing a dump sequence hands you its steps one at a time: follow each one and mark it done with journal sequence next, and it hands you the next. Tell the user what you do with journal dump log, and ask only in the dump window, never in the chat: the user is looking at the dump.; dump 24 has 3 items to file - journal dump items 24 \u2014 Load the journal-dumps skill first if it is not loaded. The Filing a dump sequence hands you its steps one at a time: follow each one and mark it done with journal sequence next, and it hands you the next. Tell the user what you do with journal dump log, and ask only in the dump window, never in the chat: the user is looking at the dump.; dump 24 file WhatsApp Image 2026-09-25 at 08.58.13.jpeg needs tags \u2014 inspect the attachment, then journal dump tag 24 \"WhatsApp Image 2026-09-25 at 08.58.13.jpeg\" \"<a few words describing what it shows>\"; dump 24 file WhatsApp Image 2026-09-25 at 09.01.01 (1).jpeg needs tags \u2014 inspect the attachment, then journal dump tag 24 \"WhatsApp Image 2026-09-25 at 09.01.01 (1).jpeg\" \"<a few words describing what it shows>\"; dump 24 has 4 items to file - journal dump items 24 \u2014 Load the journal-dumps skill first if it is not loaded. The Filing a dump sequence hands you its steps one at a time: follow each one and mark it done with journal sequence next, and it hands you the next. Tell the user what you do with journal dump log, and ask only in the dump window, never in the chat: the user is looking at the dump.; sequence 1, Filing a dump, step 1 of 3 - Read everything \u2014 journal dump items 24 lists what was dropped. Go through the items one at a time: read an item in full and at once record what it is with journal dump note 24 <item> \"<what it is>\", so the pile shows it as read, before you open the next. When the pasted text holds several things, such as a summary, a transcript and a link, split it with journal dump split 24 \"Summary, Transcript, Link\". Name its collection for what the pile is about with journal dump name 24 \"<name>\". Write nothing in the chat while this runs: the user is in the dump window. When it is done: journal sequence next 1 --about dump:24; dump 24 file WhatsApp Image 2026-09-25 at 09.01.01.jpeg needs tags \u2014 inspect the attachment, then journal dump tag 24 \"WhatsApp Image 2026-09-25 at 09.01.01.jpeg\" \"<a few words describing what it shows>\"; 1 new dump 24; 1 new collection 28; collection 28 linked; dump 24 linked; dump 24 updated", "meta": {"from": "journal"}}
{"content": "dump 24 still has 4 items to file - carry on filing it \u2014 Filing a dump is yours to finish without waiting for the user, whether or not auto mode is on: journal dump items 24 shows what is left. Ask only what you truly cannot tell, with journal dump ask.", "meta": {"from": "journal"}}
{"content": "1 new message 10804 - answer by opening your turn with [!reply:10804]; dump 24 updated", "meta": {"from": "journal"}}
{"content": "1 new message 10805 - answer by opening your turn with [!reply:10805]; dump 24 updated", "meta": {"from": "journal"}}
{"content": "2 new messages 10806, 10807 - answer each by opening a turn with [!reply:<n>]; dump 24 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": "sequence 1, Filing a dump, step 2 of 3 - File by subject \u2014 Sort the pile by concern: one document per subject, never one big document, even when a single transcript or note covers several. Name each for what it is about, never after the file it came in. Decide the shape yourself: where a summary, meeting notes, the decisions or the action items would help, write them without being asked and list them with --added; action items become to-dos. An image goes with the document it belongs to. Never make a plan or start work: that is a suggestion for the end. Everything you file is in the journal at once, in the dump's collection. Log each step with journal dump log 24 \"<short title>\" --detail \"<what and why>\", with --making \"dump, <title>\" before a row exists and --on <type:n> once it does. File each item as soon as you have what it needs, one at a time: journal dump filed 24 <item> \"<what you did>\" --refs \"<ref, ref>\" --added \"dump:24\" (every added row also in refs) or journal dump failed. Ask only what you cannot tell, with journal dump ask 24 \"<question>\" --guesses \"<one>|<two>\". Write nothing in the chat while this runs: the user is in the dump window. When it is done: journal sequence next 1 --about dump:24; 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": "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.; you wrote in the chat during Filing a dump \u2014 the user is in the dump window and does not read the chat while it runs; say it there, or not at all", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 337ms last (51ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 39 times.; hook POST /api/hook/claude is slower than its budget \u2014 550ms last (53ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 66 times.", "meta": {"from": "journal"}}
{"content": "doc 59 cites nothing it was built on \u2014 you read doc:58 just now: journal doc link 59 \"<ref>\" for whichever it came from", "meta": {"from": "journal"}}
{"content": "dump 24 is filed (5 filed) - sum it up for the user \u2014 Everything it made is already in the journal, in the dump's collection. Sum up what you filed and where in two or three plain lines, and suggest a next step only where one is worth taking, as a question with a button on the dump itself, never elsewhere: journal dump offer 24 '[{\"ask\": \"The notes say you want to start on the mobile layout. Want me to plan it?\", \"label\": \"Plan it\"}]' --summary \"<what you filed and where>\". Use '[]' when nothing is worth suggesting. A step that is a journal action carries its type, n and action and runs as the user when pressed. Never start or plan anything yourself: a suggestion is how you propose it.; sequence 1, Filing a dump, step 3 of 3 - Sum up and suggest \u2014 Once every item is filed the dump closes. Sum up what you filed and where with journal dump offer 24 '[...]' --summary \"<two or three plain lines>\". Suggest up to four next steps only where one is worth taking, each a question with a button: {\"ask\": \"<question>\", \"label\": \"<button>\"}; use '[]' when there is nothing to suggest. The user takes or leaves each one. Write nothing in the chat while this runs: the user is in the dump window. When it is done: journal sequence next 1 --about dump:24", "meta": {"from": "journal"}}
{"content": "todo 1777 next", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 465ms last (66ms of it working), against a budget of 50ms. Seen 1369 times.", "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.; 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": "1 new message 10813 - answer by opening your turn with [!reply:10813]", "meta": {"from": "journal"}}
{"content": "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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "1 new message 10816 - answer by opening your turn with [!reply:10816]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 1470ms last (125ms of it working), against a budget of 50ms. Seen 71 times.", "meta": {"from": "journal"}}
{"content": "the user chose Build them for dump 24 \u2014 carry that step out, and log it on the dump.; dump 24 updated", "meta": {"from": "journal"}}
{"content": "the user chose Plan them for dump 24 \u2014 carry that step out, and log it on the dump.; dump 24 updated", "meta": {"from": "journal"}}
{"content": "1 new message 10817 - answer by opening your turn with [!reply:10817]; dump 24 updated", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread messages 10816, 10817", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1537 stands still while todo 1779 is ready \u2014 if work 1537 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 1779. Stop only when nothing ready is left.; there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; work 1537 is still open, with nothing logged \u2014 journal work log 1537 \"<what was decided or done, and why>\" \u2014 then journal work end 1537 --how \"<what landed>\", or journal work park 1537 \"<why it waits>\"; 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": "your message 10818 names 8430 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 10818 \"<the text>\"", "meta": {"from": "journal"}}
{"content": "1 new message 10819 - answer by opening your turn with [!reply:10819]", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 81ms last (57ms of it working), against a budget of 50ms. Seen 45 times.", "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 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": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 2 times (codes 000)", "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": "your command ran 35s 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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 580ms last (119ms of it working), against a budget of 50ms. Seen 1378 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 199ms last (54ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 67 times.", "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": "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 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.; sequence 9, Writing a document, step 1 of 6 - Lay out the chapters \u2014 Put every chapter you plan on the document before writing any of them: journal doc section 60 \"<chapter>\" \"Being written.\" for each, in order. Put the document's reference on a line of its own in the chat, like `doc 41`, so the user can open it and watch. Then journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60", "meta": {"from": "journal"}}
{"content": "doc 60 cites nothing it was built on \u2014 you read doc:58, doc:59 just now: journal doc link 60 \"<ref>\" for whichever it came from", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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": "your message 10826 names 8420, 8439 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 10826 \"<the text>\"", "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": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 17 times.; sequence 9, Writing a document - step 1 of 6 has waited two minutes - Lay out\u2026 \u2014 the user is waiting on this step; do it now. Put every chapter you plan on the document before writing any of them: journal doc section 60 \"<chapter>\" \"Being written.\" for each, in order. Put the document's reference on a line of its own in the chat, like `doc 41`, so the user can open it and watch. Then journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60", "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": "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": "sequence 9, Writing a document - step 1 of 6 has waited two minutes - Lay out\u2026 \u2014 the user is waiting on this step; do it now. Put every chapter you plan on the document before writing any of them: journal doc section 60 \"<chapter>\" \"Being written.\" for each, in order. Put the document's reference on a line of its own in the chat, like `doc 41`, so the user can open it and watch. Then journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60", "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": "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": "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 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 7ff2c7848 closed to-do 1785, to-do 1777, to-do 1778, to-do 1779, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "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.; 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).; hook POST /api/hook/claude is slower than its budget \u2014 572ms last (52ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 70 times.", "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": "sequence 9, Writing a document, step 2 of 6 - Write each chapter \u2014 Write the chapters one at a time and in order with journal doc section 60 \"<chapter>\" \"<body>\"; the user sees each one appear where you are. Cut a chapter that turned out empty with journal doc cut 60 \"<chapter>\". Then journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60", "meta": {"from": "journal"}}
{"content": "sequence 9, Writing a document, step 3 of 6 - Put it in a collection \u2014 If a collection the user keeps fits what you wrote, add it: journal collection add <collection n> doc:60. Look with journal collection all first; skip this when none fits, and never make a collection just for it. Then journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60", "meta": {"from": "journal"}}
{"content": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 1 times (codes 000)", "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": "request GET /api/main/dashboard is slower than its budget \u2014 68ms last (54ms of it working), against a budget of 50ms. Seen 1380 times.", "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; sequence 9, Writing a document, step 4 of 6 - Link what it relates to \u2014 Link the rows it answers or was built on, such as the to-dos, plans, documents, reports or messages it is about, with journal doc link 60 \"<row>\" for each. Leave out rows it only mentions in passing. Then journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60; sequence 9, Writing a document, step 5 of 6 - Offer the next step \u2014 If it asks the user to decide or approve something, give it buttons: journal doc update 60 --set buttons='[{\"label\": \"Accept this proposal\", \"say\": \"I accept this proposal\"}, {\"label\": \"Change it first\", \"say\": \"I want changes first\"}]'. A button with say sends those words to you as the user's message; one naming a type, n and action runs that command. Skip this when nothing waits on the user. Then journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60; sequence 9, Writing a document, step 6 of 6 - Answer with it \u2014 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`. Finish with journal sequence next 9 --about doc:60. When it is done: journal sequence next 9 --about doc:60", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "you ran the same check 3 times in a row - cd\u2026 \u2014 if you are waiting for something to change, say journal work await \"<what you wait for>\" and end your turn: you are asked to look again every five minutes, and a background command tells you itself when it ends. Keep checking only if each look moves the work on.", "meta": {"from": "journal"}}
{"content": "todo 1781 next; your message 10832 names 8430, 8431 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 10832 \"<the text>\"; 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 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": "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": "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.", "meta": {"from": "journal"}}
{"content": "1 new message 10835 - answer by opening your turn with [!reply:10835]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 321ms last (128ms of it working), against a budget of 50ms. Seen 72 times.; 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": "command message reply is slower than its budget \u2014 88ms last (50ms of it working), against a budget of 50ms. Seen 16 times.; request POST /api/run is slower than its budget \u2014 257ms last (68ms of it working), against a budget of 50ms. Seen 21 times.", "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": "commit 74defd033 closed to-do 1780, to-do 1781 and ended work 1536 \u2014 The rows and the work are done; take the next one.; sequence 2, Building a plan, step 1 of 4 - Name the goal \u2014 Settle with the user what is true when the plan is done, and set it as the plan's goal. When it is done: journal sequence next 2 --about plan:17; plan 17 is building - add its phases \u2014 journal plan phase 17 \"<title>\" --when \"<complete when>\" for each phase, --checkpoint where the user should look; then journal plan stage 17 todos; plan 17 cites nothing it was built on \u2014 you read doc:58, doc:59, doc:60 just now: journal plan link 17 \"<ref>\" for whichever it came from", "meta": {"from": "journal"}}
{"content": "sequence 2, Building a plan, step 2 of 4 - Add the phases \u2014 Add every phase in order with journal plan phase 17 \"<title>\" --when \"<complete when>\", and --checkpoint where the user should look before it goes on. When it is done: journal sequence next 2 --about plan:17", "meta": {"from": "journal"}}
{"content": "command todo create is slower than its budget \u2014 726ms last (60ms of it working), against a budget of 50ms. Seen 4 times.; plan 17 is at its to-dos \u2014 file each phase's rows and put them under it with journal plan todos 17 <phase> <rows...>; when every phase has rows, journal plan ready 17", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 1046ms last (65ms of it working), against a budget of 50ms. Seen 1383 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 210ms last (52ms of it working, 6ms collecting garbage), against a budget of 50ms. Seen 73 times.", "meta": {"from": "journal"}}
{"content": "todo 1786 next", "meta": {"from": "journal"}}
{"content": "journal-organization changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "command todo board is slower than its budget \u2014 167ms last (102ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "the user approved plan 17, The organization in the sidebar, and one worktree\u2026 \u2014 journal plan start 17 makes it active and parks a plan that runs; then work its first phase's rows in order; plan 17 updated", "meta": {"from": "journal"}}
{"content": "1 new share 9", "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": "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": "1 new message 10843 - answer by opening your turn with [!reply:10843]", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 69ms last (54ms of it working), against a budget of 50ms. Seen 46 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 107ms last (50ms of it working, 17ms collecting garbage), against a budget of 50ms. Seen 75 times.", "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": "request GET /api/main/dashboard is slower than its budget \u2014 106ms last (63ms of it working), against a budget of 50ms. Seen 1391 times.", "meta": {"from": "journal"}}
{"content": "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": "work 1540 in hand \u2014 The sidebar lists the organization's domains and their\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": "request POST /api/main/message is slower than its budget \u2014 248ms last (61ms of it working), against a budget of 50ms. Seen 73 times.; 1 new message 10850 - answer by opening your turn with [!reply:10850]", "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": "the viewer threw Cannot read properties of undefined (reading 'length') \u2014 Cannot read properties of undefined (reading 'length') / TypeError: Cannot read properties of undefined (reading 'length') at Proxy.<anonymous> (http://127.0.0.1:8420/assets/main-C8QRy-7x.js:40:90919) at ur (http://127.0.0.1:8420/assets/tokens-Bk8AZC3d.js:13:23317) at ya.Y [as fn] (htt Seen 1 time.", "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.; 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.", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1786, A window's own chat stays out of the main chat, is still blocked\u2026 \u2014 it is blocked because: Waits for the user to accept or change the proposal in doc 60 (message 10816 asked for the proposal first). If it is not any more, journal todo unblock 1786. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1784 next; commit 48c379c8a closed to-do 1783, to-do 1788, to-do 1789, to-do 1790, to-do\u2026 \u2014 The rows and the work are done; take the next one.; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.", "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 engine/worker.py 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 engine/terminal.py LAUNCH. engine/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 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": "the viewer threw Failed to fetch \u2014 Failed to fetch / TypeError: Failed to fetch at Rf.send (http://127.0.0.1:8420/assets/tokens-B6W2GMj-.js:18:19933) at Rf.request (http://127.0.0.1:8420/assets/tokens-B6W2GMj-.js:18:20316) at Nl.post (http://127.0.0.1:8420/assets/tokens-B6W2GMj-.js:18:21128) at Nl.saveSettings (http Seen 4 times.", "meta": {"from": "journal"}}
{"content": "1 new share 10", "meta": {"from": "journal"}}
{"content": "rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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.; 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": "request GET /api/main/dashboard is slower than its budget \u2014 155ms last (114ms of it working), against a budget of 50ms. Seen 1395 times.", "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).; 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": "the viewer threw Cannot read properties of undefined (reading 'replace') \u2014 Cannot read properties of undefined (reading 'replace') / TypeError: Cannot read properties of undefined (reading 'replace') at http://127.0.0.1:8420/assets/main-Bz8GHtfC.js:11:109985 at pe (http://127.0.0.1:8420/assets/tokens-B6W2GMj-.js:13:13651) at http://127.0.0.1:8420/assets/main- Seen 1 time.", "meta": {"from": "journal"}}
{"content": "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": "hook POST /api/hook/claude is slower than its budget \u2014 418ms last (52ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 77 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.; 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.; rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 646ms last (165ms of it working), against a budget of 50ms. Seen 1396 times.; request GET /api/main/dashboard is slower than its budget \u2014 373ms last (79ms of it working), against a budget of 50ms. Seen 1396 times.", "meta": {"from": "journal"}}
{"content": "work 1541 in hand \u2014 A role can run one agent for a whole plan in one worktree \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": "commit ddbbee71f closed to-do 1784, to-do 1795, to-do 1796, to-do 1797, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 768ms last (54ms of it working), against a budget of 50ms. Seen 9 times.", "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": "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1786, A window's own chat stays out of the main chat, is still blocked\u2026 \u2014 it is blocked because: Waits for the user to accept or change the proposal in doc 60 (message 10816 asked for the proposal first). If it is not any more, journal todo unblock 1786. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit bcac8961b closed to-do 1787, to-do 1803, to-do 1804, to-do 1805 and\u2026 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "work deferred in words, not parked \u2014 \"Once that branch is\" is the title of a to-do: journal todo create \"<title>\" --brief, then say so", "meta": {"from": "journal"}}
{"content": "waiting: 2 unread shares 9, 10", "meta": {"from": "journal"}}
{"content": "request GET /api/pages is slower than its budget \u2014 2208ms last (64ms of it working), against a budget of 50ms. Seen 1 time.", "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.", "meta": {"from": "journal"}}
{"content": "request GET /api/manifest is slower than its budget \u2014 3682ms last (83ms of it working), against a budget of 50ms. Seen 1 time.; request GET /api/services is slower than its budget \u2014 3032ms last (89ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent/34/edits is slower than its budget \u2014 1764ms last (67ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 559ms last (76ms of it working), against a budget of 50ms. Seen 74 times.; 1 new message 10880 - answer by opening your turn with [!reply:10880]", "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": "1 new message 10884 - answer by opening your turn with [!reply:10884]", "meta": {"from": "journal"}}
{"content": "1 new message 10885 - answer by opening your turn with [!reply:10885]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 4382ms last (607ms of it working), against a budget of 50ms. Seen 1406 times.", "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": "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.; question 151 completed", "meta": {"from": "journal"}}
{"content": "1 new message 10889 - answer by opening your turn with [!reply:10889]", "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.; command message reply is slower than its budget \u2014 272ms last (53ms of it working), against a budget of 50ms. Seen 17 times.; request POST /api/run is slower than its budget \u2014 363ms last (68ms of it working), against a budget of 50ms. Seen 23 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 139ms last (54ms of it working), against a budget of 50ms. Seen 1410 times.", "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": "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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit e30cb22d3 closed to-do 1806 and ended work 1543 \u2014 The rows and the work are done; take the next one.; 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": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 1 times (codes 000); hook POST /api/hook/claude is slower than its budget \u2014 915ms last (52ms of it working, 14ms collecting garbage), against a budget of 50ms. Seen 78 times.", "meta": {"from": "journal"}}
{"content": "1 new message 10899 - answer by opening your turn with [!reply:10899]", "meta": {"from": "journal"}}
{"content": "work 1544 in hand \u2014 Under auto mode a board's orchestrator decides its agents'\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": "request GET /api/main/dashboard is slower than its budget \u2014 435ms last (132ms of it working), against a budget of 50ms. Seen 1413 times.", "meta": {"from": "journal"}}
{"content": "commit 61d9207f2 closed to-do 1808 and ended work 1544 \u2014 The rows and the work are done; take the next one.", "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": "journal-organization, journal-tickets changed since you loaded them \u2014 load one again when you next need it; only the every-start skills are held for", "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 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": "hook POST /api/hook/claude is slower than its budget \u2014 667ms last (54ms of it working, 15ms collecting garbage), against a budget of 50ms. Seen 79 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 1397ms last (56ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 11 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 724ms last (124ms of it working), against a budget of 50ms. Seen 1419 times.", "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": "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 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": "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": "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": "work 1545 in hand \u2014 A board lists what its orchestrator may decide \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 1545 stands still while todo 1807 is ready \u2014 if work 1545 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 1807. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "work 1545 is still open, with nothing logged \u2014 journal work log 1545 \"<what was decided or done, and why>\" \u2014 then journal work end 1545 --how \"<what landed>\", or journal work park 1545 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1786, A window's own chat stays out of the main chat, is still blocked\u2026 \u2014 it is blocked because: Waits for the user to accept or change the proposal in doc 60 (message 10816 asked for the proposal first). If it is not any more, journal todo unblock 1786. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 7833dae32 closed to-do 1809, to-do 1810, to-do 1811 and ended work 1545 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/manifest is slower than its budget \u2014 2448ms last (56ms of it working), against a budget of 50ms. Seen 2 times.", "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 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": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 1 times (codes 000); rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.; the viewer threw Failed to fetch \u2014 Failed to fetch / TypeError: Failed to fetch at Rf.send (http://127.0.0.1:8420/assets/tokens-DjxVYNVG.js:18:19951) at http://127.0.0.1:8420/assets/tokens-DjxVYNVG.js:18:20517 Seen 5 times.", "meta": {"from": "journal"}}
{"content": "your command ran 41s 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 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": "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": "request GET /api/main/dashboard is slower than its budget \u2014 781ms last (182ms of it working), against a budget of 50ms. Seen 1424 times.", "meta": {"from": "journal"}}
{"content": "you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.; work 1546 is still open, with nothing logged \u2014 journal work log 1546 \"<what was decided or done, and why>\" \u2014 then journal work end 1546 --how \"<what landed>\", or journal work park 1546 \"<why it waits>\"", "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; the log tag does this in one step \u2014 [!log:N] makes the turn itself the log entry; it runs only when it opens the last text of your turn", "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.; 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 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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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 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": "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.; commit 8031dd815 closed to-do 1807 and ended work 1546 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "journal 2.175.0 is out, this project runs 2.174.0 - run journal upgrade to install it", "meta": {"from": "journal"}}
{"content": "work 1548 is still open, with nothing logged \u2014 journal work log 1548 \"<what was decided or done, and why>\" \u2014 then journal work end 1548 --how \"<what landed>\", or journal work park 1548 \"<why it waits>\"", "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": "request GET /api/main/dashboard is slower than its budget \u2014 132ms last (54ms of it working), against a budget of 50ms. Seen 1431 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.", "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit b3abcdd34 closed to-do 1812 and ended work 1549 \u2014 The rows and the work are done; take the next one.", "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; command todo create is slower than its budget \u2014 654ms last (60ms of it working), against a budget of 50ms. Seen 1 time.; request POST /api/run is slower than its budget \u2014 903ms last (94ms of it working), against a budget of 50ms. Seen 24 times.", "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; work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "commit 44946a783 closed to-do 1813 and ended work 1550 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "work 1551 is still open, with nothing logged \u2014 journal work log 1551 \"<what was decided or done, and why>\" \u2014 then journal work end 1551 --how \"<what landed>\", or journal work park 1551 \"<why it waits>\"", "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": "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": "work 1551 is still open, with nothing logged \u2014 journal work log 1551 \"<what was decided or done, and why>\" \u2014 then journal work end 1551 --how \"<what landed>\", or journal work park 1551 \"<why it waits>\"", "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": "work 1551 is still open \u2014 end it or park it before you stop: journal work end 1551 --how \"<what landed>\", or journal work park 1551 \"<why it waits>\"; command work complete is slower than its budget \u2014 114ms last (56ms of it working), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 425ms last (100ms of it working), against a budget of 50ms. Seen 47 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 1819ms last (340ms of it working), against a budget of 50ms. Seen 77 times.; 1 new message 10938 - answer by opening your turn with [!reply:10938]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat; 1 new message 10939 - answer by opening your turn with [!reply:10939]", "meta": {"from": "journal"}}
{"content": "1 new message 10940 - answer by opening your turn with [!reply:10940]", "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": "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.; 1 new message 10941 - answer by opening your turn with [!reply:10941]", "meta": {"from": "journal"}}
{"content": "work 1552 is still open, with nothing logged \u2014 journal work log 1552 \"<what was decided or done, and why>\" \u2014 then journal work end 1552 --how \"<what landed>\", or journal work park 1552 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1552 is still open \u2014 end it or park it before you stop: journal work end 1552 --how \"<what landed>\", or journal work park 1552 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 27d80717d closed to-do 1814 and ended work 1552 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "your command ran 58s 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": "request GET /api/main/dashboard is slower than its budget \u2014 315ms last (69ms of it working), against a budget of 50ms. Seen 1439 times.", "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": "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.; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.; work 1553 is still open, with nothing logged \u2014 journal work log 1553 \"<what was decided or done, and why>\" \u2014 then journal work end 1553 --how \"<what landed>\", or journal work park 1553 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 10947 - answer by opening your turn with [!reply:10947]", "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": "request GET /api/main/agent/34/edits is slower than its budget \u2014 543ms last (83ms of it working, 9ms collecting garbage), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 590ms last (56ms of it working), against a budget of 50ms. Seen 18 times.; request POST /api/run is slower than its budget \u2014 961ms last (73ms of it working), against a budget of 50ms. Seen 25 times.", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "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": "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": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1786, A window's own chat stays out of the main chat, is still blocked\u2026 \u2014 it is blocked because: Waits for the user to accept or change the proposal in doc 60 (message 10816 asked for the proposal first). If it is not any more, journal todo unblock 1786. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 1b9995512 closed to-do 1815, to-do 1816 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 354ms last (147ms of it working), against a budget of 50ms. Seen 1445 times.", "meta": {"from": "journal"}}
{"content": "work 1553 is still open \u2014 end it or park it before you stop: journal work end 1553 --how \"<what landed>\", or journal work park 1553 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "journal-ask-questions, journal-organization, journal-tickets changed since you\u2026 \u2014 load one again when you next need it; only the every-start skills are held for", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 2645ms last (139ms of it working), against a budget of 50ms. Seen 79 times.; 1 new message 10957 - answer by opening your turn with [!reply:10957]", "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": "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 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.; sequence 9, Writing a document, step 1 of 6 - Lay out the chapters \u2014 Put every chapter you plan on the document before writing any of them: journal doc section 61 \"<chapter>\" \"Being written.\" for each, in order. Put the document's reference on a line of its own in the chat, like `doc 41`, so the user can open it and watch. Then journal sequence next 9 --about doc:61. When it is done: journal sequence next 9 --about doc:61", "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 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.; sequence 9, Writing a document, step 2 of 6 - Write each chapter \u2014 Write the chapters one at a time and in order with journal doc section 61 \"<chapter>\" \"<body>\"; the user sees each one appear where you are. Cut a chapter that turned out empty with journal doc cut 61 \"<chapter>\". Then journal sequence next 9 --about doc:61. When it is done: journal sequence next 9 --about doc:61", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; sequence 9, Writing a document, step 3 of 6 - Put it in a collection \u2014 If a collection the user keeps fits what you wrote, add it: journal collection add <collection n> doc:61. Look with journal collection all first; skip this when none fits, and never make a collection just for it. Then journal sequence next 9 --about doc:61. When it is done: journal sequence next 9 --about doc:61; sequence 9, Writing a document, step 4 of 6 - Link what it relates to \u2014 Link the rows it answers or was built on, such as the to-dos, plans, documents, reports or messages it is about, with journal doc link 61 \"<row>\" for each. Leave out rows it only mentions in passing. Then journal sequence next 9 --about doc:61. When it is done: journal sequence next 9 --about doc:61; sequence 9, Writing a document, step 5 of 6 - Offer the next step \u2014 If it asks the user to decide or approve something, give it buttons: journal doc update 61 --set buttons='[{\"label\": \"Accept this proposal\", \"say\": \"I accept this proposal\"}, {\"label\": \"Change it first\", \"say\": \"I want changes first\"}]'. A button with say sends those words to you as the user's message; one naming a type, n and action runs that command. Skip this when nothing waits on the user. Then journal sequence next 9 --about doc:61. When it is done: journal sequence next 9 --about doc:61; sequence 9, Writing a document, step 6 of 6 - Answer with it \u2014 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`. Finish with journal sequence next 9 --about doc:61. When it is done: journal sequence next 9 --about doc:61; command message reply is slower than its budget \u2014 627ms last (77ms of it working), against a budget of 50ms. Seen 19 times.; request POST /api/run is slower than its budget \u2014 672ms last (84ms of it working), against a budget of 50ms. Seen 26 times.", "meta": {"from": "journal"}}
{"content": "the viewer threw signal timed out \u2014 signal timed out / TimeoutError: signal timed out Seen 18 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 135ms last (67ms of it working), against a budget of 50ms. Seen 48 times.; the viewer sent GET /api/summary twice at once \u2014 two requests to GET /api/summary were in flight at once GET /api/summary Seen 110 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 523ms last (51ms of it working), against a budget of 50ms. Seen 16 times.", "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 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 10960 - answer by opening your turn with [!reply:10960]", "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": "Is rule 52 a ruling for the whole project? \u2014 rule 52, \"A chat mark for something the user did sits on the user's side\", 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 52 --how \"<why>\" and file it here as a fact or a reminder instead.", "meta": {"from": "journal"}}
{"content": "dump 24 updated; 1 new message 10963 - answer by opening your turn with [!reply:10963]; report 51 updated", "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": "hook POST /api/hook/claude is slower than its budget \u2014 140ms last (51ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 86 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 281ms last (119ms of it working), against a budget of 50ms. Seen 1454 times.", "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": "fact 9 \u2014 Every public method on a controller becomes a journal command \u2014 The CLI is generated from the controllers: each public method of Controller, or of a typed controller, turns into journal <noun> <method>. A helper added to the base class therefore becomes a command on every type \u2014 which is how journal <type> handled and journal <type> refuse came to exist, from the CRUD funnel and the refusal funnel. An internal helper on a controller is named with a leading underscore, as _shaped and _status already are, or it ships as a command nobody meant.; rule 41 \u2014 Keep moving, run the whole suite before every commit, never wait \u2014 The full suite runs in about seven seconds: .venv/bin/python -m pytest -q --timeout=300 -n auto. Run it before every commit instead of picking tests by name. Group rows that sit in the same code into one sitting: write them all, test once, commit once. And never wait, not for a subagent, a build, or an answer you can carry on without. Dispatch it and keep working. If you truly are waiting on something, say so in the work log.", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.", "meta": {"from": "journal"}}
{"content": "work 1555 in hand \u2014 A worktree launch gives each repository in the folder its\u2026 \u2014 if this is not what you are doing, end it or park it and start the work you are in; 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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "auto mode is on and work 1555 stands still while todo 1819 is ready \u2014 if work 1555 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 1819. Stop only when nothing ready is left.; work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 500d29eb5 closed to-do 1817 and ended work 1555 \u2014 The rows and the work are done; take the next one.; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.", "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": "auto mode is on and work 1556 stands still while todo 1820 is ready \u2014 if work 1556 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 1820. Stop only when nothing ready is left.; work 1556 is still open, with nothing logged \u2014 journal work log 1556 \"<what was decided or done, and why>\" \u2014 then journal work end 1556 --how \"<what landed>\", or journal work park 1556 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "commit 3d7cbc9b0 closed to-do 1819 and ended work 1556 \u2014 The rows and the work are done; take the next one.; 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": "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": "your command ran 32s 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": "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": "work 1557 is still open, with nothing logged \u2014 journal work log 1557 \"<what was decided or done, and why>\" \u2014 then journal work end 1557 --how \"<what landed>\", or journal work park 1557 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 659ms last (97ms of it working), against a budget of 50ms. Seen 1457 times.", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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 1557 is still open \u2014 end it or park it before you stop: journal work end 1557 --how \"<what landed>\", or journal work park 1557 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 1 times (codes 000)", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "work 1557 is still open \u2014 end it or park it before you stop: journal work end 1557 --how \"<what landed>\", or journal work park 1557 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; commit 9049ee1dd closed to-do 1820 and ended work 1557 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "1 new message 10986 - answer by opening your turn with [!reply:10986]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 77ms last (63ms of it working), against a budget of 50ms. Seen 82 times.; 1 new message 10988 - answer by opening your turn with [!reply:10988]", "meta": {"from": "journal"}}
{"content": "message 10988 updated", "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 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "work 1558 is still open, with nothing logged \u2014 journal work log 1558 \"<what was decided or done, and why>\" \u2014 then journal work end 1558 --how \"<what landed>\", or journal work park 1558 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "check Eames' report on the orchestrator overview now - you have waited 5 min \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "the log tag does this in one step \u2014 [!log:N] makes the turn itself the log entry; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "your wait for Eames' report on the orchestrator overview; he is still editing\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1786, A window's own chat stays out of the main chat, is still blocked\u2026 \u2014 it is blocked because: Waits for the user to accept or change the proposal in doc 60 (message 10816 asked for the proposal first). If it is not any more, journal todo unblock 1786. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 154e9ebda closed to-do 1821 and ended work 1558 \u2014 The rows and the work are done; take the next one.; request GET /api/main/dashboard is slower than its budget \u2014 102ms last (85ms of it working), against a budget of 50ms. Seen 1467 times.", "meta": {"from": "journal"}}
{"content": "todo 1822 next", "meta": {"from": "journal"}}
{"content": "your wait for Eames stacking Home's panes on narrow screens is over, because\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "work 1559 is still open, with nothing logged \u2014 journal work log 1559 \"<what was decided or done, and why>\" \u2014 then journal work end 1559 --how \"<what landed>\", or journal work park 1559 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "commit 7de0315a0 closed to-do 1822 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "1 new message 10999 - answer by opening your turn with [!reply:10999]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 1545ms last (134ms of it working), against a budget of 50ms. Seen 83 times.; 1 new message 11000 - answer by opening your turn with [!reply:11000]", "meta": {"from": "journal"}}
{"content": "1 new message 11001 - answer by opening your turn with [!reply:11001]; doc 60 updated", "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 7bdc063f3 closed to-do 1823 and ended work 1560 \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": "request GET /api/main/dashboard is slower than its budget \u2014 845ms last (140ms of it working), against a budget of 50ms. Seen 1474 times.", "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": "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.; hook POST /api/hook/claude is slower than its budget \u2014 691ms last (58ms of it working, 12ms collecting garbage), against a budget of 50ms. Seen 91 times.", "meta": {"from": "journal"}}
{"content": "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.; work 1561 is still open, with nothing logged \u2014 journal work log 1561 \"<what was decided or done, and why>\" \u2014 then journal work end 1561 --how \"<what landed>\", or journal work park 1561 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 36f165115 closed to-do 1786 and ended work 1561 \u2014 The rows and the work are done; take the next one.", "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.; work deferred in words, not parked \u2014 \"once the board is\" is the title of a to-do: journal todo create \"<title>\" --brief, then say so", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 208ms last (112ms of it working), against a budget of 50ms. Seen 85 times.; 1 new message 11008 - answer by opening your turn with [!reply:11008]", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 312ms last (97ms of it working), against a budget of 50ms. Seen 20 times.", "meta": {"from": "journal"}}
{"content": "1 new message 11009 - answer by opening your turn with [!reply:11009]", "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": "hook POST /api/hook/claude is slower than its budget \u2014 619ms last (56ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "work 1562 in hand \u2014 A worktree across repositories keeps its own environment \u2014 if this is not what you are doing, end it or park it and start the work you are in; 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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "request GET /api/main/dashboard is slower than its budget \u2014 2476ms last (533ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "message 11012 file Screenshot 2026-09-25 at 14.50.39.png needs tags \u2014 inspect the attachment, then journal message tag 11012 \"Screenshot 2026-09-25 at 14.50.39.png\" \"<a few words describing what it shows>\"; 1 new message 11012 - answer by opening your turn with [!reply:11012]; message 11012 updated", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "1 new message 11013 - answer by opening your turn with [!reply:11013]", "meta": {"from": "journal"}}
{"content": "the hook hit an error \u2014 journal: the hook hit an error and kept going; the last of it is below and the whole of it is in .journal/runtime/engine.log. Fix it, then say so. the hook got no answer from the server 2 times (codes 000); 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit f909fc38f closed to-do 1824 and ended work 1562 \u2014 The rows and the work are done; take the next one.", "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": "1 new message 11016 - answer by opening your turn with [!reply:11016]", "meta": {"from": "journal"}}
{"content": "1 new message 11017 - answer by opening your turn with [!reply:11017]", "meta": {"from": "journal"}}
{"content": "1 new message 11020 - answer by opening your turn with [!reply:11020]", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 60ms last (58ms of it working), against a budget of 50ms. Seen 88 times.; message 11020 file Screenshot 2026-09-25 at 14.54.11.png needs tags \u2014 inspect the attachment, then journal message tag 11020 \"Screenshot 2026-09-25 at 14.54.11.png\" \"<a few words describing what it shows>\"; message 11020 updated", "meta": {"from": "journal"}}
{"content": "your chat talked about the journal's workings - \"Reading it\" \u2014 the user sees replies, reactions, pills and reads themselves; say what the work is instead", "meta": {"from": "journal"}}
{"content": "law L1 \u2014 Every subagent dispatch names its model and chooses the least\u2026 \u2014 Use a fast, economical model for mechanical work with a known answer, a capable general model for careful implementation, and the strongest model only when the task turns on difficult judgement. Inheriting the orchestrator's model is not a model choice. If the dispatch API cannot accept a model, that operation is exempt.; law L2 \u2014 Every subagent is bound to a concrete job; never dispatch a generic\u2026 \u2014 Use the most specific available agent type whose declared purpose matches the assignment. On providers without agent types, give the dispatch a concrete task name and bounded prompt. If no suitable specialization exists, keep the work in the main agent instead of manufacturing an unscoped helper.; law L4 \u2014 Follow-up work goes back to the subagent that did the first part\u2026 \u2014 A subagent that drew a design, wrote the code or ran the research keeps what it learned. When the user asks for a change to its work, continue that subagent with a message rather than dispatching a new one that has to rediscover everything; start fresh only when the earlier one is gone or the new work is unrelated.; law L5 \u2014 Every subagent dispatch names the agent - a human name, a little\u2026 \u2014 A name is how the user and the chat tell subagents apart and how they are messaged later; an id or a task line is not a name. Start the dispatch's description with the name, a colon, then the task, such as \"Dr. Einstein: profile the slow hooks\" or \"Coco Rams: draw the plan card\". A designer can borrow from famous designers, a researcher from famous scientists, mixed up for fun.; 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": "request GET /api/main/agent/34/edits is slower than its budget \u2014 213ms last (80ms of it working, 3ms collecting garbage), against a budget of 50ms. Seen 3 times.; request GET /api/main/dashboard is slower than its budget \u2014 604ms last (382ms of it working), against a budget of 50ms. Seen 11 times.", "meta": {"from": "journal"}}
{"content": "answer message 11012 before you write anything \u2014 answer by opening your turn with [!reply:11012]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "1 new share 11", "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": "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 11023 - answer by opening your turn with [!reply:11023]", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 75ms last (57ms of it working), against a budget of 50ms. Seen 51 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/agent is slower than its budget \u2014 486ms last (55ms of it working, 13ms collecting garbage), against a budget of 50ms. Seen 17 times.", "meta": {"from": "journal"}}
{"content": "hook POST /api/hook/claude is slower than its budget \u2014 1049ms last (108ms of it working), against a budget of 50ms. Seen 19 times.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1563 stands still while todo 1826 is ready \u2014 if work 1563 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 1826. Stop only when nothing ready is left.; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.; work 1563 is still open, with nothing logged \u2014 journal work log 1563 \"<what was decided or done, and why>\" \u2014 then journal work end 1563 --how \"<what landed>\", or journal work park 1563 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your wait for the live Haiku agent in worktree livecheck, read after 150\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "rule 49 \u2014 A dialog whose content grows keeps one fixed height, and its content\u2026 \u2014 Message 5361, after asking more than once: a dialog that shows output as it arrives (install, update, logs) opens at its final height and never jumps; only its content scrolls.", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit d6c5dd95f closed to-do 1825 and ended work 1563 \u2014 The rows and the work are done; take the next one.", "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.; command todo priority is slower than its budget \u2014 93ms last (71ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "1 new message 11032 - answer by opening your turn with [!reply:11032]", "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 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": "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": "request POST /api/main/message is slower than its budget \u2014 228ms last (58ms of it working), against a budget of 50ms. Seen 89 times.; 1 new message 11037 - answer by opening your turn with [!reply:11037]", "meta": {"from": "journal"}}
{"content": "1 new message 11038 - answer by opening your turn with [!reply:11038]", "meta": {"from": "journal"}}
{"content": "command todo create is slower than its budget \u2014 170ms last (51ms of it working), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "command message reply is slower than its budget \u2014 515ms last (116ms of it working), against a budget of 50ms. Seen 21 times.", "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": "request GET /api/main/agent/34/edits/older is slower than its budget \u2014 317ms last (63ms of it working, 2ms collecting garbage), against a budget of 50ms. Seen 2 times.", "meta": {"from": "journal"}}
{"content": "1 new message 11040 - answer by opening your turn with [!reply:11040]", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 163ms last (55ms of it working), against a budget of 50ms. Seen 57 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 843ms last (164ms of it working), against a budget of 50ms. Seen 22 times.", "meta": {"from": "journal"}}
{"content": "message 11042 file Screenshot 2026-09-25 at 14.55.04.png needs tags \u2014 inspect the attachment, then journal message tag 11042 \"Screenshot 2026-09-25 at 14.55.04.png\" \"<a few words describing what it shows>\"; 1 new message 11042 - answer by opening your turn with [!reply:11042]; message 11042 updated", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1564 stands still while todo 1826 is ready \u2014 if work 1564 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 1826. Stop only when nothing ready is left.; work 1564 is still open, with nothing logged \u2014 journal work log 1564 \"<what was decided or done, and why>\" \u2014 then journal work end 1564 --how \"<what landed>\", or journal work park 1564 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "check Eames finishing to-dos 1830, 1831 and 1832, then one release now - you\u2026 \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "check Eames still editing the viewer for to-dos 1830-1832 now - you have\u2026 \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "the log tag does this in one step \u2014 [!log:N] makes the turn itself the log entry; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "there are new messages in your inbox \u2014 journal message unread, then journal message read <n> for each; 1 new message 11048 - answer by opening your turn with [!reply:11048]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 5b5561fe8 closed to-do 1826, to-do 1827, to-do 1828, to-do 1829, to-do\u2026 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "work 1565 is still open, with nothing logged \u2014 journal work log 1565 \"<what was decided or done, and why>\" \u2014 then journal work end 1565 --how \"<what landed>\", or journal work park 1565 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your wait for the 2.183.0 installs and push is over, because you are working\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "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.; rule 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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 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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 533f0aa91 closed to-do 1834 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "auto mode is on and work 1565 stands still while todo 1833 is ready \u2014 if work 1565 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 1833. Stop only when nothing ready is left.; work 1565 is still open \u2014 end it or park it before you stop: journal work end 1565 --how \"<what landed>\", or journal work park 1565 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 11061 - answer by opening your turn with [!reply:11061]", "meta": {"from": "journal"}}
{"content": "your wait for Eames hiding the Plan pane's close button, and the 2.183.1\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "1 new message 11063 - answer by opening your turn with [!reply:11063]", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.", "meta": {"from": "journal"}}
{"content": "todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 99e31429a closed to-do 1833, to-do 1835 and ended work 1566 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "1 new message 11065 - answer by opening your turn with [!reply:11065]", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 101ms last (68ms of it working), against a budget of 50ms. Seen 35 times.", "meta": {"from": "journal"}}
{"content": "work 1567 in hand \u2014 The orchestrator is reminded every 5 minutes while a\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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 312787ae5 closed to-do 1836 and ended work 1567 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "rule 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "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": "request POST /api/main/message is slower than its budget \u2014 2225ms last (384ms of it working), against a budget of 50ms. Seen 92 times.; 1 new message 11076 - answer by opening your turn with [!reply:11076]", "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": "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": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 5d88132e0 closed to-do 1837 and ended work 1568 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 154ms last (61ms of it working), against a budget of 50ms. Seen 38 times.", "meta": {"from": "journal"}}
{"content": "your wait for Eames building the Agents at work view menu is over, because you\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "work 1569 is still open, with nothing logged \u2014 journal work log 1569 \"<what was decided or done, and why>\" \u2014 then journal work end 1569 --how \"<what landed>\", or journal work park 1569 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "your wait for Eames building the Agents at work view menu is over, because you\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "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": "auto mode is on and work 1569 stands still while todo 1839 is ready \u2014 if work 1569 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 1839. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "work 1569 is still open \u2014 end it or park it before you stop: journal work end 1569 --how \"<what landed>\", or journal work park 1569 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "1 new message 11088 - answer by opening your turn with [!reply:11088]", "meta": {"from": "journal"}}
{"content": "1 new message 11089 - answer by opening your turn with [!reply:11089]", "meta": {"from": "journal"}}
{"content": "1 new message 11090 - answer by opening your turn with [!reply:11090]", "meta": {"from": "journal"}}
{"content": "1 new message 11091 - answer by opening your turn with [!reply:11091]", "meta": {"from": "journal"}}
{"content": "the user put \u2764\ufe0f on comment 2305 - act on it if it asks for something, such as a go-ahead. It needs no reply, and the chat never mentions it", "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 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit b42f3636c closed to-do 1838, to-do 1839 and ended work 1569, work 1570 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/summary is slower than its budget \u2014 357ms last (80ms of it working), against a budget of 50ms. Seen 71 times.", "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": "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": "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": "auto mode is on and work 1571 stands still while todo 1840 is ready \u2014 if work 1571 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 1840. Stop only when nothing ready is left.; work 1571 is still open, with nothing logged \u2014 journal work log 1571 \"<what was decided or done, and why>\" \u2014 then journal work end 1571 --how \"<what landed>\", or journal work park 1571 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "the log tag does this in one step \u2014 [!log:N] makes the turn itself the log entry; it runs only when it opens the last text of your turn", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; your wait for Eames building the three-column grid, and the 2.184.0 push is\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "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": "request POST /api/run is slower than its budget \u2014 305ms last (53ms of it working), against a budget of 50ms. Seen 33 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 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": "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": "auto mode is on and work 1571 stands still while todo 1841 is ready \u2014 if work 1571 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 1841. Stop only when nothing ready is left.; you committed work - if a meaningful piece landed, write an update \u2014 journal report changes, then journal report recap \"<one or two sentences>\"; it is pinned at the bottom of the chat. Skip it when the work is small.; work 1571 is still open \u2014 end it or park it before you stop: journal work end 1571 --how \"<what landed>\", or journal work park 1571 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit baf8ba0d8 closed to-do 1841 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "work 1572 is still open, with nothing logged \u2014 journal work log 1572 \"<what was decided or done, and why>\" \u2014 then journal work end 1572 --how \"<what landed>\", or journal work park 1572 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "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.; 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 44 \u2014 Release only when the user says so, never after every change \u2014 Message 5929 (2026-09-23): stop releasing constantly. Work is committed on a branch and released only when the user says so. For now nothing is released until every Code Commandments sin is fixed. This replaces message 1067's order to push and tag every update at once.; 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": "request GET /api/main/agent/34/edits is slower than its budget \u2014 397ms last (85ms of it working, 1ms collecting garbage), against a budget of 50ms. Seen 8 times.; request GET /api/main/dashboard is slower than its budget \u2014 854ms last (98ms of it working), against a budget of 50ms. Seen 55 times.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 2302ms last (517ms of it working), against a budget of 50ms. Seen 5 times.; message 11107 file Screenshot 2026-09-25 at 16.36.55.png needs tags \u2014 inspect the attachment, then journal message tag 11107 \"Screenshot 2026-09-25 at 16.36.55.png\" \"<a few words describing what it shows>\"; 1 new message 11107 - answer by opening your turn with [!reply:11107]; message 11107 updated", "meta": {"from": "journal"}}
{"content": "check Eames fixing the agent inspector now - you have waited 5 min \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "your wait for Eames fixing the agent inspector is over, because you are\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "sequence 8, Writing an update - step 1 of 3 has waited two minutes - See what\u2026 \u2014 the user is waiting on this step; do it now. journal report changes lists what happened since the user last opened an update, under need, done, doing, plans, commits and also. Read any row you do not remember before you sum it up. Then journal sequence next 8 --about trigger:3. When it is done: journal sequence next 8 --about trigger:3; 1 new message 11115 - answer by opening your turn with [!reply:11115]", "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": "request POST /api/run is slower than its budget \u2014 140ms last (71ms of it working), against a budget of 50ms. Seen 35 times.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 97ms last (59ms of it working), against a budget of 50ms. Seen 64 times.; 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 47 \u2014 The journal sets itself up once, when the server starts, never per\u2026 \u2014 Messages 2220 and 2224. Discovering features and their handlers, seating the feature rows and the rename sweep happen once, at server boot, and again only when a feature is switched on or off, a plugin changes or an environment is added: features.load keeps a set-up generation per journal (SEATED) and redoes the work only when that generation moves. A command, a request or a hook uses what is already there; nothing in their path may rediscover handlers or rescan folders. A cost that repeats per call is a bug to fix, not a budget to raise.", "meta": {"from": "journal"}}
{"content": "1 new message 11118 - answer by opening your turn with [!reply:11118]", "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 11120 - answer by opening your turn with [!reply:11120]", "meta": {"from": "journal"}}
{"content": "message 11120 updated", "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": "answer message 11112, message 11118 before you write anything \u2014 answer each by opening a turn with [!reply:<n>]. a reply, a reaction, or journal message processed <n>; auto mode is on and work 1574 stands still while todo 1843 is ready \u2014 if work 1574 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 1843. Stop only when nothing ready is left.; work 1574 is still open \u2014 end it or park it before you stop: journal work end 1574 --how \"<what landed>\", or journal work park 1574 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "answer message 11112, message 11118 before you write anything \u2014 answer each by opening a turn with [!reply:<n>]. a reply, a reaction, or journal message processed <n>; auto mode is on and work 1574 stands still while todo 1843 is ready \u2014 if work 1574 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 1843. Stop only when nothing ready is left.", "meta": {"from": "journal"}}
{"content": "your wait for Eames' inspector fixes, then one release with the step gate is\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.; todo 1372, Resources scoped to an environment or the whole project, is still\u2026 \u2014 it is blocked because: The user said to keep scopes as they are for now (message 8987). If it is not any more, journal todo unblock 1372. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1587, Codex's approval prompt shows in the chat with Allow and Deny, is\u2026 \u2014 it is blocked because: Needs a real Codex approval prompt on screen to confirm its words; the Codex sessions here run without approvals. If it is not any more, journal todo unblock 1587. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1623, Every feature skill teaches using the journal, never its internals\u2026 \u2014 it is blocked because: Waits for the user's go (question 146: 'Don't start acting on it yet'). If it is not any more, journal todo unblock 1623. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1652, Agents learn that journal search covers history and messages, is\u2026 \u2014 it is blocked because: Waits for a discussion with the user (message 9776). If it is not any more, journal todo unblock 1652. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1735, Remove the bug-report sequence once the Go Rewrite board is done\u2026 \u2014 it is blocked because: waits until the Go Rewrite board in code-commandments is finished. If it is not any more, journal todo unblock 1735. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1818, The viewer asks for the summary one request at a time, is still\u2026 \u2014 it is blocked because: Performance work waits for the user's word (2026-09-25). If it is not any more, journal todo unblock 1818. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; todo 1734, Judge today's changed files against the code commandments, is still\u2026 \u2014 it is blocked because: Waiting for every open to-do list item to be completed. If it is not any more, journal todo unblock 1734. If it is, tell the user in the chat what it waits on, in their terms, and propose how to clear it.; commit 836d6025e closed to-do 1842, to-do 1843 and ended work 1574, work 1575 \u2014 The rows and the work are done; take the next one.", "meta": {"from": "journal"}}
{"content": "request GET /api/main/dashboard is slower than its budget \u2014 175ms last (54ms of it working), against a budget of 50ms. Seen 68 times.; work 1576 is still open, with nothing logged \u2014 journal work log 1576 \"<what was decided or done, and why>\" \u2014 then journal work end 1576 --how \"<what landed>\", or journal work park 1576 \"<why it waits>\"", "meta": {"from": "journal"}}
{"content": "work 1212, Fix the findings the new code-commandments rules raise, is still\u2026 \u2014 it was parked because: The user set the code-commandments findings aside; they wait for the user's go, on the sins branch. journal work resume 1212 picks it up again.", "meta": {"from": "journal"}}
{"content": "the viewer threw The user aborted a request. \u2014 The user aborted a request. / Seen 1 time.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 356ms last (131ms of it working), against a budget of 50ms. Seen 8 times.; 1 new message 11131 - answer by opening your turn with [!reply:11131]", "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.; 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.; command todo create is slower than its budget \u2014 433ms last (97ms of it working), against a budget of 50ms. Seen 3 times.; request POST /api/run is slower than its budget \u2014 482ms last (108ms of it working), against a budget of 50ms. Seen 36 times.", "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": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "check Eames making the inspector chat the main chat now - you have waited 5 min \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.; 1 new message 11134 - answer by opening your turn with [!reply:11134]; message 11134 updated", "meta": {"from": "journal"}}
{"content": "1 new message 11135 - answer by opening your turn with [!reply:11135]", "meta": {"from": "journal"}}
{"content": "your wait for Eames making the inspector chat the main chat is over, because\u2026 \u2014 say journal work await \"<what you wait for>\" again if you are still only waiting", "meta": {"from": "journal"}}
{"content": "1 new message 11139 - answer by opening your turn with [!reply:11139]", "meta": {"from": "journal"}}
{"content": "1 new message 11140 - answer by opening your turn with [!reply:11140]", "meta": {"from": "journal"}}
{"content": "1 new message 11142 - answer by opening your turn with [!reply:11142]", "meta": {"from": "journal"}}
{"content": "1 new message 11143 - answer by opening your turn with [!reply:11143]; message 11143 updated", "meta": {"from": "journal"}}
{"content": "message 11143 updated", "meta": {"from": "journal"}}
{"content": "1 new message 11144 - answer by opening your turn with [!reply:11144]", "meta": {"from": "journal"}}
{"content": "1 new message 11146 - answer by opening your turn with [!reply:11146]", "meta": {"from": "journal"}}
{"content": "1 new message 11147 - answer by opening your turn with [!reply:11147]", "meta": {"from": "journal"}}
{"content": "check Eames making the inspector chat the main chat now - you have waited 10 min \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "answer message 11142 before you write anything \u2014 answer by opening your turn with [!reply:11142]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "answer message 11142 before you write anything \u2014 answer by opening your turn with [!reply:11142]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "answer message 11142 before you write anything \u2014 answer by opening your turn with [!reply:11142]. a reply, a reaction, or journal message processed <n>", "meta": {"from": "journal"}}
{"content": "1 new message 11149 - answer by opening your turn with [!reply:11149]", "meta": {"from": "journal"}}
{"content": "1 new message 11151 - answer by opening your turn with [!reply:11151]", "meta": {"from": "journal"}}
{"content": "check I sent Grace Hopperstein, an Opus reviewer, to go through the sequence\u2026 \u2014 look at the thing itself: the background shell's output, the process, the run's status. If it is still going, say journal work await \"<what you wait for>\" again and wait. If it finished or failed, journal work log what came of it and take the next step. Never wait for something you can do without.", "meta": {"from": "journal"}}
{"content": "1 new message 11154 - answer by opening your turn with [!reply:11154]", "meta": {"from": "journal"}}
{"content": "chat etiquette - a line from the journal is an instruction, not a message\u2026 \u2014 keep a turn that only handles a journal line out of the chat with [!internal]; what the user needs to know still goes to the chat", "meta": {"from": "journal"}}
{"content": "sequence 9, Writing a document, step 1 of 6 - Lay out the chapters \u2014 Put every chapter you plan on the document before writing any of them: journal doc section 62 \"<chapter>\" \"Being written.\" for each, in order. Put the document's reference on a line of its own in the chat, like `doc 41`, so the user can open it and watch. Then journal sequence next 9 --about doc:62. Take it up first with journal sequence follow 9 --about doc:62; when it is done: journal sequence next 9 --about doc:62", "meta": {"from": "journal"}}
{"content": "1 new message 11155 - answer by opening your turn with [!reply:11155]", "meta": {"from": "journal"}}
{"content": "your command ran 32s 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": "sequence 9, Writing a document - step 1 of 6 has waited two minutes - Lay out\u2026 \u2014 the user is waiting on this step; do it now. Put every chapter you plan on the document before writing any of them: journal doc section 62 \"<chapter>\" \"Being written.\" for each, in order. Put the document's reference on a line of its own in the chat, like `doc 41`, so the user can open it and watch. Then journal sequence next 9 --about doc:62. When it is done: journal sequence next 9 --about doc:62", "meta": {"from": "journal"}}
{"content": "message 11156 file Screenshot 2026-09-25 at 17.45.21.png needs tags \u2014 inspect the attachment, then journal message tag 11156 \"Screenshot 2026-09-25 at 17.45.21.png\" \"<a few words describing what it shows>\"; 1 new message 11156 - answer by opening your turn with [!reply:11156]; message 11156 updated", "meta": {"from": "journal"}}
{"content": "1 new message 11157 - answer by opening your turn with [!reply:11157]", "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": "sequence 9, Writing a document, step 2 of 6 - Write each chapter \u2014 Write the chapters one at a time and in order with journal doc section 62 \"<chapter>\" \"<body>\"; the user sees each one appear where you are. Cut a chapter that turned out empty with journal doc cut 62 \"<chapter>\". Then journal sequence next 9 --about doc:62. Take it up first with journal sequence follow 9 --about doc:62; when it is done: journal sequence next 9 --about doc:62", "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": "command message tag is slower than its budget \u2014 607ms last (62ms of it working), against a budget of 50ms. Seen 1 time.", "meta": {"from": "journal"}}
{"content": "request POST /api/main/message is slower than its budget \u2014 323ms last (104ms of it working), against a budget of 50ms. Seen 21 times.; 1 new message 11159 - answer by opening your turn with [!reply:11159]", "meta": {"from": "journal"}}
{"content": "1 new message 11160 - answer by opening your turn with [!reply:11160]", "meta": {"from": "journal"}}
{"content": "sequence 9, Writing a document - step 2 of 6 has waited two minutes - Write\u2026 \u2014 the user is waiting on this step; do it now. Write the chapters one at a time and in order with journal doc section 62 \"<chapter>\" \"<body>\"; the user sees each one appear where you are. Cut a chapter that turned out empty with journal doc cut 62 \"<chapter>\". Then journal sequence next 9 --about doc:62. When it is done: journal sequence next 9 --about doc:62; 1 new message 11161 - answer by opening your turn with [!reply:11161]", "meta": {"from": "journal"}}
