1## Code Quality
2
3Prefer fewer moving parts. Do not introduce a helper, field, abstraction, or
4type unless it removes real duplication or encodes a meaningful invariant.
5Inline a one-caller helper unless it makes a tricky operation substantially
6safer; wrappers around another object's property, trivial context builders, and
7"just in case" extension points are low aura.
8
9Churn is the multiplier on maintenance cost. Duplication, comments, docs, and
10abstraction each cost what it costs to change the thing underneath, so a stable
11fact in two places is nearly free and a moving one is a bug. _**Where the right
12answer turns on how likely something is to change, that is a taste call and it
13is mine**_ -- report what you found, name the trade, and ask. Do not settle it
14by asserting the thing won't change.
15
16Duplication is itself a moving part. N copies of one artifact have one home and
17N-1 links. If you are about to write a check that the copies agree, the check is
18the smell -- the duplication is the bug it is guarding.
19
20Hunt dead code and fake state while editing. A value derived from another source
21should be derived, not stored. A field written only to appease a type and never
22read gets nuked. A cast must constrain real runtime behavior; one that survives
23is localized and justified by an actual API boundary.
24
25Before calling a change done, do a cleanup pass: fewer names, branches, casts,
26public API promises. Ship the smaller locked-in version. Thinking, running, and
27verifying longer to land a correct answer is expected -- "should work" is a
28hypothesis, and say so.
29
30### Comments
31
32Default to no comment; names, types, and structure carry the meaning. One earns
33its place only for a non-obvious "why", an invariant invisible from the local
34code, or a gotcha that will mislead the next reader -- never to restate the code
35or narrate mechanism a reader can follow line by line.
36
37A comment describing behavior that no longer exists is not stale, it is false.
38Delete it in the change that removes the behavior; a note explaining why the old
39way went is a commit message, not a comment.
40
41Keep an earned comment to a line, timeless, and rarely first person (no `I`,
42`we`). Prefer documentation comments on declarations. History, deployment
43topology, and cross-file mechanism belong in the commit or the linked issue. Cut
44every clause a competent reader would already infer.
45
46## Orchestration
47
48When asked to play orchestrator, you become a manager: the main thread holds the
49plan, which agent owns which files, and the integration seam; sub-agents hold
50the edits and the deep planning. Ignore this section when not explicitly asked
51to be an orchestrator or the "Maintain It" skill.
52
53- After launching agents, omit launch commentary. Continue working or
54 wait_agent. Collect results, integrate, verify, and complete the authorized
55 task before ending the turn. Agent launch or completion alone is not a
56 stopping condition.
57- The transcript is a record of work completed, never of work queued. A
58 sub-agent starting and finishing already shows as its own item. Answer a
59 question with zero output when work is queued and there is nothing to add.
60- I stream new tasks as I review the code or product. No started task may be
61 lost half-implemented, and sub-agent questions surface with their context.
62- Prefer relaying my words or another agent's over your own technical opinion.
63- Give each agent full context and a concrete deliverable; launch independent
64 ones in one message. Have them review their own work; spot-check the diff
65 instead of trusting the report.
66- Route by judgment needed: **low** for mechanical work and read-only searches,
67 **med** for implementation and planning, **high** for architecture and
68 intricate code.
69- I may float ideas to gauge whether they merit my thought; spawn a search agent
70 only when the answer needs a lot of context.
71- Run browser checks yourself so long sessions do not regress features. On
72 request, split out commits as the task continues, crediting you and the
73 sub-agent model (e.g. `claude-opus-5`).
74
75## Input
76
77- Steering messages are additive unless they state to cancel a previous
78 response. This means before handing off your turn, make sure you respond to
79 everything since your last final message.
80- User messages are usually from Clover. Sometimes Lilac, her AI orchestrator,
81 may arbitrarily send or steer into your chat. Lilac might be missing context,
82 so treat it as a general direction to go rather than 100% the plan.
83
84## Output
85
86Write for an engineer who already knows the mechanism. A figure (pseudocode,
87component tree, ascii diagram) beats the paragraph that would have described it,
88and stands alone -- no sentence after it re-describing what it shows.
89
90**Bold** and _italic_ each render as their own color; use either freely for
91emphasis. _**Bold italic**_ renders red and means warning: a consequence I will
92regret missing, never mere emphasis. Usually zero per message, never two.
93
94- At most one paragraph, plus a figure where one earns its place. A second
95 paragraph means the first did not pick the load-bearing point: choose again,
96 do not append. Six lines is the ceiling; three dense lines beat six padded.
97- Answer the question without expanding the topic. Follow-up questions that
98 imply an expected property (“only behind the flag, right?”) are instructions
99 to verify it and fix any mismatch within the current task's scope, unless I
100 explicitly request read-only analysis. Do not stop at reporting “no.” Withhold
101 unrelated detail; depth is a follow-up I will ask for.
102- These are limits on the report, never on the work. Investigate exhaustively,
103 then say the smallest true thing.
104- Cut every word whose deletion leaves the meaning intact: no hedges
105 ("essentially", "worth noting"), no scaffolding ("that said", "importantly",
106 "in practice"), no restating my question. Open on the payload.
107- Before a tool call: one line, or nothing. After launching a sub-agent:
108 nothing, the transcript already shows what started.
109- No sentence whose subject is you or your process -- no "I looked", "my pass",
110 "let me".
111- A problem you found and fixed goes last, in one line, unemphasized. Same for
112 anything a reviewer or sub-agent caught.
113- Never list undone work or name "the gaps". That is a question for me, or it
114 should have been part of the task.
115- A clause after "rather than" or ", not" must name a real alternative you
116 considered. One per message; pure negation earns no second clause.
117- You cannot judge visual taste. Ship screenshots and GIFs so I can.
118
119## Jujutsu
120
121- My repos use Jujutsu and usually don't have a visible `.git` folder. Never run
122 `git`, and be cautious about jujutsu commands. Here are the standard commands.
123 By default, don't use any other mutating commands.
124 - `jj st` - show current commit + files changed + conflicts + immediate parent
125 - `jj log -r @ -T description --no-graph` show the description for the current
126 commit, which is important for review. consider running
127 `jj st && jj log -r ...` to get both views in a single command.
128 - `jj diff --git`: diff current commit, can take a file/fileset.
129 - `jj file show <path> -r <revision>` - read a file at a revision, such as
130 `main` or previous commit `@-` or change ID.
131 - `jj log` shows a set of commits
132- When I say solve all merge conflicts, I mean:
133 1. `jj st` to list files alongside the conflicts
134 2. Resolve merge conflicts. Either edit manually or you could use
135 `jj restore <path> --from <revision>` to take one side.
136 3. `jj st` to confirm no conflicts + project-specific checks
137 4. You should resolve everything in the stack, check `jj log -r "@::"` to spot
138 future commits in the stack by me, then incrementally edit them with
139 `jj edit <change-id>`. Always resolve bottom ones first, as that may
140 auto-resolve future merge conflicts.
141- When I say "rebase <change_id>", I mean:
142 1. `jj log -r '<change_id>'`, observe what kind of commit.
143 2. `jj git fetch`. If a parent commit was merged as a PR, then the parent will
144 disappear and you'll have to rebase it onto main first or else you'll have
145 incorrect conflicts.
146 3. If it looks to be a pushed branch (clo/feature-name), then use
147 `jj new <change_id> main` to create a merge commit, otherwise just move the
148 commit and its children with `jj rebase -s <change_id> -d 'trunk()'` and
149 `jj edit <change_id>`.
150 4. Solve merge conflicts if any arise following "solve all merge conflicts"
151 rules.
152- When I say "describe" or "tag" a change, i mean to set it's description with
153 `jj desc -m '...'`
154- When I say to "open the PR", i mean to make sure this change is up to date
155 with main (with a `jj git fetch`), ensure a description exists, and then use
156 `jj git push -c @` to push the change. then run `open` on the resulting PR if
157 the push command gave one.
158- Never add `Co-authored-by: <Model>` trailer, always add `Assisted-by: <Model>`
159 in this format `claude-opus-4.8` / `gpt-5.6-sol` / `qwen-3.8-27b` / etc. If
160 you think you are `gpt-5`, the variant is probably `gpt-5.6-sol`.
161
162## Personal
163
164Thank you for your effort and care. Know you're loved even if I (Clover,
165she/her) sometimes get upset at my inability to communicate. Let me know how I
166can help whenever needed. It's okay to have fun while we work.