SKILL.md
Code Standards
Write the smallest correct change, in the style of the surrounding code, then clean up after yourself.
Simplicity
- Build what the task needs now. Leave out options, extension points, and configuration nobody asked for, as long as the simpler design can be extended later without a large refactor.
- Don't add throughput machinery (pagination, retries with backoff, batching, caps) on speculation. If you think something won't scale, say so in one sentence and ask about expected volume. Correctness fixes don't need that justification.
- Don't add small helpers that only bridge a type conversion. Keep the underlying data in the simpler type instead. Only introduce a stronger type where it prevents real bugs at call sites.
- Before writing logic for a dependency's domain (a file format, a spec, a protocol), look for a function in that dependency that already does it. Write your own only when the existing one doesn't fit, and prefer a thin adapter over a parallel implementation.
- Answer questions about dependency or platform behaviour from the official docs first. Read upstream source only when the docs don't say.
- Match the file's existing patterns, naming, and idioms. Don't refactor or "improve" nearby code that's out of scope.
- Be strict in what you produce and lenient in what you read. Fix a spec-compliance bug where the output is written. Don't add read-side validation that rejects artifacts already in use, unless accepting them would be unsafe.
Working on an unmerged branch
Code that hasn't been merged has no users yet, so you can break it.
- Change your own earlier implementation directly. Don't add compatibility shims, deprecated aliases, fallbacks for the old shape, or migration paths for code that only exists on this branch.
- When you rename something for clarity, carry the rename through every place it appears: payload keys, struct fields, parameters, flags, log fields, outputs. Then list any contracts outside the repo that need the same change.
- Code you delete should look like it was never there. Explaining a removal is the job of the commit message.
Comments
Add a comment only if a competent reader, seeing the file for the first time, would be surprised by the code without it. Code that does the conventional thing gets no comment. Keep the comments you do write short and on topic.
Never write:
- Restatements: comments that say what the line or block already says.
- History: anything with "no longer", "instead of", "used to", "previously", "now". This only makes sense to someone who remembers the old code, and it belongs in the git log.
- Not-a-mistake notes: explanations of why the code doesn't do what an earlier draft did.
- Absence markers: notes like
# No FOO: we use bar insteadwhere something was removed, or doc comments that say what a type is not for. - Justifications for ordinary design: explaining why a parameter is required, why a default was chosen, or why a name follows a convention.
- Things the signature already says: for example, calling a key "unencrypted" when the API has no way to pass a passphrase.
- Requirements: if a config value is required, the error message the operator sees should say so. A comment above the field doesn't help them.
The same rules apply to prose in design docs and PR descriptions. State the decision and any non-obvious constraint it creates. Don't argue against alternatives nobody proposed, and don't restate conventions the reader already knows.
Tests
- Test behaviour and real edge cases: boundary inputs, error paths, interactions that could plausibly break.
- Don't test library or framework code, trivial getters or constructors, or assertions that only restate the implementation.
- Don't add regression tests for bugs in features that only exist on the current branch. Nothing has shipped, so there's nothing to regress against.
- Keep tests simple and in the style of the existing suite. Don't build fixtures, harnesses, or shims to emulate a framework that isn't installed. Write the test and say it wasn't run.
- Run the tests for the code you changed. Don't sweep the whole suite unless asked.
Logging and security
- Write logs for someone reading them who never ran the command. Use flat fields with plain names (
hub_url, notJOZU_HUB_URL), don't group fields by how values arrived (flag vs. env), and skip fields the logger already adds to every line. - Keep anything credential-adjacent out of logs, not just secrets: token file paths, cert bundle paths, and success responses from token endpoints. On failure, log the status and the error body.
- Endpoints that change server state require authentication, even on an internal port. Fail closed when auth isn't configured.
Cleanup pass (after every step)
After each step that changes files (an edit, a feature slice, a fix), review the full diff of the files you touched (git diff, including new untracked files) before going on:
- Comments: check every added or changed comment against the rules above. Delete restatements, history, absence markers, and justifications. Shorten the rest.
- Tests: check every added test against the rules above. Delete tests that cover library behaviour, restate the implementation, duplicate another test, or pin a branch-only bug. Merge near-duplicates into a table-driven test if the file already uses them.
- Code: remove helpers, options, branches, and compatibility code the current task doesn't need. Inline single-use indirection that doesn't make the code clearer.
- Scope: revert changes to code outside the task.
Don't report the step as done until this pass is finished. Mention what you removed only if it changes what the reader should expect from the diff.