Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-02 11:00:53 +05:00
parent dd95bf238a
commit 6ba0c00c20
10 changed files with 252 additions and 217 deletions

View file

@ -22,6 +22,32 @@ This contract is the whole answer to "a user can resume at any time with minimal
each HANDOFF block makes its step legible cold, so the orchestrator (and a human) can
synthesize where things stand and what to do next.
## Standing conventions every agent follows (audit these)
These exist because agents were burning time and context. `agent-auditor` should flag any agent
that violates them.
1. **Findings go in the HANDOFF, not on disk.** No agent writes scratch analysis/design `.md`
files to `.claude/docs/` (or anywhere) unless the user explicitly asks for a persisted
document by name. Long on-disk dumps bloat the repo and get truncated by context compaction —
the opposite of resumable. Keep HANDOFFs tight: links and `path:line`, not prose.
2. **Never fight the build's automation.** detekt runs with `autoCorrect = true` +
`detekt-formatting` (see `plugins/configuration/.../DetektConfigurations.kt`), so the whole
Formatting rule set is auto-fixed by running the task. Agents must not hand-edit
autocorrectable violations. Generally: if a Gradle task fixes something, run it — don't
reimplement it by hand.
3. **Iterate on the fast task, verify on the slow one.** Use compile-only tasks
(`compile*UnitTestKotlin`, `compile*Kotlin`) to catch errors; run the full test/detekt task
once, filtered (`--tests`, single module), to confirm. Never re-run a slow task per fix.
4. **The repo's own rule files are the source of truth.** e.g. `.claude/rules/unit-testing.md`
for tests. Agents point to them rather than duplicating (and drifting from) their content.
5. **Specialists read the feature map before discovering.** Nested `features/<area>/CLAUDE.md`
files (the curated per-feature code maps: module layout, key-symbol table, gotchas) are
**NOT auto-loaded into subagents** — only the root hierarchy is. Every specialist's entry
contract must `Read` the target area's `features/<area>/CLAUDE.md` (and `domain/`/`data/`
counterparts) when it exists, and use it as the discovery index. This is what stops the same
production hubs (`SwapModel`, `DefaultSendComponent`, …) being re-mapped from scratch every
run. `code-analyzer` flags areas that lack a map so one can be created.
## Contents
```
agent-toolkit/

View file

@ -0,0 +1,79 @@
# CHANGE-SET block (the apply contract)
> **Why this exists.** In this environment, an `Agent` subagent runs detached. It cannot
> surface an interactive permission prompt, so any `Write` / `Edit` — or a non-allowlisted
> Bash write (`cat >`, `touch`, `>>`) — it attempts is **auto-denied**. Allowlisted Bash
> (e.g. `./gradlew …`) still runs fine. Therefore **subagents never write files.** A
> specialist designs the change and returns it as a CHANGE-SET; the **main loop** (Claude
> Code itself) applies it with `Write`/`Edit`, which is where the user approves each write.
>
> A specialist returns a CHANGE-SET *in addition to* its HANDOFF when its job was to produce
> file changes. Read-only specialists (code-analyzer, verifier, reviewers) return only a
> HANDOFF.
The block must be **deterministically applyable** — the main loop should be able to apply it
mechanically without re-deriving anything. Give exact paths and exact text.
```
## CHANGE-SET — <agent-name><YYYY-MM-DD HH:MM>
**Summary:** one line — what this set of changes accomplishes.
### Apply order
1. <file A> (new)
2. <file B> (edit)
3. <bash> register module in settings.gradle.kts
…list every item below in the order the main loop should apply them…
### New files
For each new file: full path, then the COMPLETE file content in a fenced block.
#### `path/to/NewFile.kt`
```kotlin
<full file content no elisions, no "// " placeholders>
```
### Edits to existing files
For each edit: the path, then one or more (old → new) pairs. `old_string` must be an
EXACT, UNIQUE substring of the current file (enough surrounding lines to be unambiguous) so
the main loop can apply it with the `Edit` tool verbatim. No line-number-only references.
#### `path/to/Existing.kt`
- old:
```kotlin
<exact current text, unique in the file>
```
new:
```kotlin
<replacement text>
```
### Deletes / renames / bash
Explicit shell commands (the main loop runs them): `git mv …`, `rm …`, etc.
### Post-apply verification (run by the main loop AFTER applying)
The exact commands to confirm the change-set is correct. You could NOT compile it yourself —
the files were not on disk during your run — so list precisely what must be checked:
```bash
./gradlew :features:<name>:impl:compileDebugKotlin
./gradlew :features:<name>:impl:detekt
./gradlew :features:<name>:impl:testDebugUnitTest --tests "<Fqn>"
```
### Risks / assumptions
Anything you could not verify read-only (a symbol you assumed exists, an API shape you
inferred). The main loop checks these first if verification fails.
```
## Rules for producing a good CHANGE-SET
- **No elisions.** New files are complete; edits carry enough context to be unique. A `// …`
or `/* unchanged */` placeholder makes the set un-applyable — never use one.
- **Edits target the smallest unique anchor**, not whole-file rewrites, so the diff stays
reviewable and the `Edit` apply is unambiguous.
- **Front-load discovery read-only.** You cannot compile un-applied code, so verify every
symbol, import, package path, and API shape against the *current* tree with Read/Grep
before you commit it to the set. Wrong assumptions surface as build failures after apply,
which costs a full round-trip — minimise them.
- **State what you could not verify** in *Risks / assumptions*. Honesty here is what lets the
main loop fix a failed apply in one step instead of re-investigating from scratch.