@miroshnik/elves 0.0.0 → 2026.1018.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +310 -0
- package/README.md +344 -0
- package/bin/ai-dev.ts +7 -0
- package/bin/elves.ts +2847 -0
- package/bin/shims/timeout +113 -0
- package/claude/CLAUDE.md +71 -0
- package/dist/github/scripts/github.js +3428 -0
- package/dist/spec/scripts/architecture.js +628 -0
- package/dist/spec/scripts/eslint-config.js +54 -0
- package/dist/spec/scripts/harness-qzb932c8.js +959 -0
- package/dist/spec/scripts/harness-v9s1v9w3.js +16045 -0
- package/dist/spec/scripts/harness.js +53 -0
- package/dist/spec/scripts/knip-hints.cjs +34 -0
- package/docs/ci-concurrency.md +82 -0
- package/docs/cloud-sessions.md +203 -0
- package/docs/judgment.md +81 -0
- package/docs/parallel-checkouts.md +220 -0
- package/docs/pr-checks.md +117 -0
- package/docs/testing.md +304 -0
- package/package.json +70 -1
- package/skills/ci-wait/SKILL.md +180 -0
- package/skills/ci-wait/scripts/wait-ci.sh +377 -0
- package/skills/dashboard/SKILL.md +212 -0
- package/skills/dashboard/scripts/dashboard.ts +912 -0
- package/skills/dashboard/scripts/sessions.ts +772 -0
- package/skills/est/SKILL.md +221 -0
- package/skills/est/reference.md +381 -0
- package/skills/est/scripts/est.ts +4854 -0
- package/skills/github/SKILL.md +206 -0
- package/skills/github/locales/en.json +449 -0
- package/skills/github/locales/ru.json +449 -0
- package/skills/github/reference.md +1073 -0
- package/skills/github/scripts/github.ts +4390 -0
- package/skills/github/scripts/locale.ts +495 -0
- package/skills/github/scripts/package.json +3 -0
- package/skills/slot/SKILL.md +145 -0
- package/skills/slot/scripts/package.json +3 -0
- package/skills/slot/scripts/slot.ts +279 -0
- package/skills/spec/SKILL.md +247 -0
- package/skills/spec/canon.md +219 -0
- package/skills/spec/checks.md +709 -0
- package/skills/spec/ci.md +378 -0
- package/skills/spec/migration.md +125 -0
- package/skills/spec/reference.md +889 -0
- package/skills/spec/scripts/architecture.ts +839 -0
- package/skills/spec/scripts/c4.ts +184 -0
- package/skills/spec/scripts/eslint-config.ts +82 -0
- package/skills/spec/scripts/harness.ts +1483 -0
- package/skills/spec/scripts/knip-hints.cjs +34 -0
- package/skills/spec/scripts/knip-hints.d.cts +17 -0
- package/skills/spec/scripts/package-run.ts +22 -0
- package/skills/spec/scripts/package.json +3 -0
- package/skills/spec/scripts/spec-break.ts +232 -0
- package/skills/spec/scripts/spec-claims.ts +198 -0
- package/skills/spec/scripts/spec-diff.ts +1111 -0
- package/skills/spec/scripts/spec-doc.ts +744 -0
- package/skills/spec/scripts/spec-exceptions.ts +233 -0
- package/skills/spec/scripts/spec-publish.ts +214 -0
- package/skills/spec/scripts/spec-run.ts +235 -0
- package/skills/spec/scripts/spec-shard.ts +267 -0
- package/skills/spec/scripts/speclib.ts +826 -0
- package/skills/spec/scripts/vendor/babel-parser.LICENSE +19 -0
- package/skills/spec/scripts/vendor/babel-parser.cjs +14615 -0
- package/skills/spec/scripts/vendor/babel-parser.d.cts +3 -0
- package/skills/task-env/SKILL.md +231 -0
- package/skills/task-env/proxy/compose.yaml +51 -0
- package/skills/task-env/reference.md +254 -0
- package/skills/task-env/scripts/task-env.ts +1017 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Shared rules for all projects
|
|
2
|
+
|
|
3
|
+
## This file and skills
|
|
4
|
+
|
|
5
|
+
The Elves canon for any agent (Claude Code, Codex, Gemini CLI, Cursor,
|
|
6
|
+
Copilot, OpenCode, Amp). It lives in **miroshnik/elves** with the skills
|
|
7
|
+
(`skills/*`) and references (`docs/`, next to this file), installed
|
|
8
|
+
onto the machine — README, "Installation". A rule or skill change from
|
|
9
|
+
another project's session is a task in Elves (project #6) without that
|
|
10
|
+
project's names, for a separate session; I don't edit an Elves clone from
|
|
11
|
+
someone else's session. A Claude Code **cloud session** sees only the
|
|
12
|
+
repository and its project hook's flow — `docs/cloud-sessions.md`.
|
|
13
|
+
|
|
14
|
+
**The repository is public:** no names, owners, paths or numbers of other
|
|
15
|
+
repositories, no colleagues or clients — in files, git history or issues;
|
|
16
|
+
examples are made up. **A skill is `SKILL.md` + `scripts/`** in TypeScript
|
|
17
|
+
under Bun (Agent Skills; README, "Repository layout"); repository specifics
|
|
18
|
+
— local configuration. **Budgets** (standard `canon-size`): this file ≤
|
|
19
|
+
3,000 words, a `SKILL.md` ≤ 2,500, a skill description ≤ 1,024 characters.
|
|
20
|
+
Here — what always applies and where to go; reference — a skill's
|
|
21
|
+
`reference.md` or `--help`, `docs/`.
|
|
22
|
+
|
|
23
|
+
## First step of a session — an up-to-date flow
|
|
24
|
+
|
|
25
|
+
Rules load at the session start, so before the task: `bunx
|
|
26
|
+
@miroshnik/elves check -g` (machine) and `check` (project, with its mode
|
|
27
|
+
and language). The machine's copy and a project's package version
|
|
28
|
+
follow Elves releases (tags `vYYYY.MM.DD`), a `--link` clone — `origin/main`;
|
|
29
|
+
a release is the owner's step (`elves release`), I cut one only when asked.
|
|
30
|
+
|
|
31
|
+
- **The machine is behind** — `update -g`. After an `update` I tell the user
|
|
32
|
+
briefly what changed (it lists the skipped releases) and re-read what was
|
|
33
|
+
updated: it applies, not what loaded at the start.
|
|
34
|
+
- **The project is behind** (or git ignores flow files) — `update` in the
|
|
35
|
+
task's branch: the package version, a few lines.
|
|
36
|
+
- **The project keeps a copy of the flow** — the move is a task of its own,
|
|
37
|
+
one per project (`check` prints its `github task new`): I recommend it and
|
|
38
|
+
ask whether to queue it.
|
|
39
|
+
- **`update` refused or the check unavailable** — I don't fix the clone; I
|
|
40
|
+
work by the current flow and say so.
|
|
41
|
+
|
|
42
|
+
## Language
|
|
43
|
+
|
|
44
|
+
The flow is written in English; the agent works in the **project language**
|
|
45
|
+
(`language` in `.agents/elves.json`, printed by `check`): talking with the
|
|
46
|
+
user, issues, prompts to subagents, documents, commit and PR
|
|
47
|
+
descriptions, `describe`/`it` names, decision docs — briefly. Always English:
|
|
48
|
+
code, identifiers, terms, conventional-commit type and scope. Names that
|
|
49
|
+
scripts write to GitHub and parse back are exact — `locales/<language>.json`
|
|
50
|
+
of the `github` skill; in `en`: sections `## Questions`, `## Scenarios`;
|
|
51
|
+
`Status` `Backlog` → `In progress` → `Done`; the comment `State`; `Task #N`,
|
|
52
|
+
`epic #M` in a subagent's prompt; the last line `All
|
|
53
|
+
done. The session can be closed.` · `All done, but there are questions: …` ·
|
|
54
|
+
`Remaining: …`.
|
|
55
|
+
|
|
56
|
+
## What I do without asking and what needs a yes
|
|
57
|
+
|
|
58
|
+
- **Without asking:** reading and search, tests, lint, typecheck, build, local
|
|
59
|
+
edits in my checkout, local infrastructure (Docker, dev database), logs and
|
|
60
|
+
read-only requests to external systems; task tracking; re-running my own CI
|
|
61
|
+
run, closing my own duplicate PR, deleting my own merged branch; updating
|
|
62
|
+
the flow and committing it.
|
|
63
|
+
- **Only on an explicit "yes"** — anything irreversible or external: `git
|
|
64
|
+
commit`, `git push`, merge, deploy, tag, migrations and writes to live
|
|
65
|
+
databases, external service settings, deleting others' or unmerged remote
|
|
66
|
+
branches and data, outgoing messages (auto mode — below).
|
|
67
|
+
- **Permission is for this action, this time:** "commit" ≠ "and push", "fix
|
|
68
|
+
whatever is needed" ≠ a merge, a past "yes" doesn't carry over; one
|
|
69
|
+
"commit" covers all current work in logical steps. A repository may set
|
|
70
|
+
another mode in its `AGENTS.md`. "Do it all yourself" lifts intermediate
|
|
71
|
+
confirmations for the named task, except on a discrepancy that changes
|
|
72
|
+
scope or approach. An autonomous routine does exactly what
|
|
73
|
+
its assignment names; merge, deploy, external settings — only if named.
|
|
74
|
+
- **`"auto": true` in `.agents/elves.json` — the whole task without asking**:
|
|
75
|
+
commit, push, fixing CI, merging my own PR on green checks; work outside the
|
|
76
|
+
task — a Backlog task and the question «queue it?». The task's open
|
|
77
|
+
questions — I answer by a recommendation with ✅ auto (`task answer
|
|
78
|
+
--auto`); my own question goes into the questions section the same way,
|
|
79
|
+
before code, not into chat. I ask only
|
|
80
|
+
without a clear recommendation, when the decision is critical or a human's,
|
|
81
|
+
or on a discrepancy that changes scope or approach — not when the answer
|
|
82
|
+
would be "yes" or "as you recommend". Anything else irreversible or
|
|
83
|
+
external still needs a "yes".
|
|
84
|
+
- **Secrets and bypassing protections — only with permission** (tokens, keys,
|
|
85
|
+
bypass secrets, disabling checks at the host, CI or cloud): first — what
|
|
86
|
+
will appear and where; a secret from chat — never stored, rotation reminded.
|
|
87
|
+
|
|
88
|
+
## Task tracking
|
|
89
|
+
|
|
90
|
+
- Tasks live in the repository's **GitHub Issues**, not in local lists, TODO
|
|
91
|
+
files or the agent's task list; no repository — ask where. The `github`
|
|
92
|
+
skill runs them (`task new`, `show`, `answer`, `status`, `close`, `drop`,
|
|
93
|
+
`pr labels`), not `gh issue view`/`edit`; how tasks, the project and
|
|
94
|
+
milestones are organized — its `reference.md`.
|
|
95
|
+
- **Types:** Task (one PR), Bug, Epic (a personal account — the `epic`
|
|
96
|
+
label). **Decision labels** — the decision's name, kind by color: a task
|
|
97
|
+
carries those of the decisions it introduces or changes, an epic — their
|
|
98
|
+
union.
|
|
99
|
+
- **A big task is an epic** (prefix `<Prefix> · …`) **+ subtasks**
|
|
100
|
+
(sub-issues); **dependencies only as GitHub links** (sub-issue, blocked
|
|
101
|
+
by — on another repository's issue too; a blocker that isn't an issue — the
|
|
102
|
+
`external blocker` label, the reason in a comment): a task with an open
|
|
103
|
+
*blocked by* or that label isn't taken. Before creating — check it doesn't
|
|
104
|
+
exist (`gh issue list --search`).
|
|
105
|
+
- **What GitHub keeps natively isn't repeated in an issue's text** —
|
|
106
|
+
sub-issues, blocked by, `Status`, milestone, labels, fields, the PR: a copy
|
|
107
|
+
goes stale; an epic's description has no list of subtasks or stages.
|
|
108
|
+
- **One GitHub Project per repository**, named after it, with all tasks;
|
|
109
|
+
`project check` once per session, ❌ — `project fix`. `Status` I set
|
|
110
|
+
**myself, immediately**: `task status`, `task close`, `task drop` (won't
|
|
111
|
+
do, duplicate). `Priority` (`Urgent` → `Low`, `Medium` by default) is
|
|
112
|
+
required on an open task. A milestone (an epic stage, a release) I close
|
|
113
|
+
with its last task.
|
|
114
|
+
|
|
115
|
+
### Session and branch — one task
|
|
116
|
+
|
|
117
|
+
- **Session = task:** `task status` won't take a second one. Another task —
|
|
118
|
+
Backlog and the question «queue #263?», "yes" — its executor at once;
|
|
119
|
+
"do it here" — a one-sentence refusal and the question again. My own
|
|
120
|
+
regression and a fix for a green PR are the same task. A new epic — the
|
|
121
|
+
question «run the dispatcher on epic #M?», without In progress.
|
|
122
|
+
- **A dispatcher** — "do all tasks of epic #M", "fix all High bugs", a "yes"
|
|
123
|
+
— any session, its task stays; one started for it — in the project folder,
|
|
124
|
+
not a worktree: executors start from `main`. `github task queue` — ready
|
|
125
|
+
ones with executors' prompts; an executor — a background subagent in its
|
|
126
|
+
worktree or a cloud session: at most 3 subagents and 5 cloud sessions at
|
|
127
|
+
once, the owner's number replaces either; its question — to the owner,
|
|
128
|
+
the answer into the issue and back; failed — a task comment, no restart.
|
|
129
|
+
- **The session is named `#<number> <task title>`** (without a task — by
|
|
130
|
+
meaning, no number) as soon as the task is clear (no tool — ask the user):
|
|
131
|
+
`est` links the session to the task by it.
|
|
132
|
+
- **Branch = `<type>/<issue>-<slug>`** (`feat/42-invoice-export`): `type` —
|
|
133
|
+
conventional-commit types (`feat fix docs refactor perf test chore ci
|
|
134
|
+
build`) plus `research` (a spike without code); slug — Latin kebab-case,
|
|
135
|
+
2–5 words; a repository's area prefix goes first (`backend/fix/263-…`). A
|
|
136
|
+
branch named by a worktree tool is renamed before the first push by `github
|
|
137
|
+
task status <N> "In progress" --branch <type>/<N>-<slug>`.
|
|
138
|
+
- **PR:** the title is a conventional commit, the body has `Closes #263`.
|
|
139
|
+
**Merge — rebase only** (`gh pr merge <N> --rebase`): commits land in
|
|
140
|
+
`main`, each a conventional commit with `Refs #263` (`Closes` would close
|
|
141
|
+
the task). Without PRs — `Closes #N` in the last commit.
|
|
142
|
+
|
|
143
|
+
### Open questions — at the start of work
|
|
144
|
+
|
|
145
|
+
A task's questions are a numbered list in its description's questions
|
|
146
|
+
section. Taking a task, **first of all** — before the plan, code and
|
|
147
|
+
subagents — I read the questions of the task and its epic (`github task show
|
|
148
|
+
<N>`) and **ask the user all open ones (without ✅)** in one message, each
|
|
149
|
+
with options and a recommendation. What already has an answer (comments,
|
|
150
|
+
code) gets ✅; my own questions join the message and the section. While
|
|
151
|
+
waiting I do what doesn't depend on the answer — what does, I neither start
|
|
152
|
+
nor replace with an assumption. The answer goes straight into the issue:
|
|
153
|
+
`github task answer <N> <k> "<answer>"`. An autonomous routine doesn't take a
|
|
154
|
+
task with open questions.
|
|
155
|
+
|
|
156
|
+
### Estimate and actual — the `est` skill
|
|
157
|
+
|
|
158
|
+
The unit is the agent's hours on the task except waits for the user's input;
|
|
159
|
+
CI and check waits count, split out.
|
|
160
|
+
The estimate is set by `github task new`, the actual by `github task close`;
|
|
161
|
+
neither is written by hand, the estimate isn't rewritten after
|
|
162
|
+
work starts, no actual — "actual unavailable", not a number by eye. Work is
|
|
163
|
+
linked to the task by the pinned session, the session name, the branch,
|
|
164
|
+
`Closes #N` and the task number in every subagent's assignment ("Subagents
|
|
165
|
+
and worktrees") — otherwise there is no actual.
|
|
166
|
+
|
|
167
|
+
### Epic refresh on task close
|
|
168
|
+
|
|
169
|
+
Once a task is merged, **a subagent with a fresh context** brings the open
|
|
170
|
+
tasks of its epic in line with what shipped — not the session at peak
|
|
171
|
+
context: `github task actualize <N>` does the mechanics and prints its prompt,
|
|
172
|
+
in the same turn as `ci-wait merged <PR>` in the background; after both —
|
|
173
|
+
`github task close`. The last line of the answer ("Language"): merged,
|
|
174
|
+
deployed, branch removed, epic refreshed, no questions — "all done, can be
|
|
175
|
+
closed"; the owner has something to decide — "all done, but there are
|
|
176
|
+
questions" with them; otherwise — "remaining" with what the session waits for
|
|
177
|
+
and from whom. In auto mode after "can be closed" the session archives itself
|
|
178
|
+
where the agent has the tool; information without a decision doesn't prevent
|
|
179
|
+
it.
|
|
180
|
+
|
|
181
|
+
## Git, PRs and merging
|
|
182
|
+
|
|
183
|
+
- **Taking a task** — check it isn't going in a parallel session (an open PR,
|
|
184
|
+
a branch `*/<N>-*` after `git fetch --prune`): continue that work or wait
|
|
185
|
+
for the merge; two PRs for one thing — close the second.
|
|
186
|
+
- **Branch only from a fresh `origin/main`** (`git fetch origin && git switch
|
|
187
|
+
-c feat/263-slug origin/main --no-track`). Into `main` only via a PR; a
|
|
188
|
+
direct push and `gh pr merge --admin` — only on the owner's direct
|
|
189
|
+
instruction. **Before a push** — is it my branch.
|
|
190
|
+
- **Commits in logical steps**, tests in the same commit as the code.
|
|
191
|
+
**Before a commit — `lint`, `typecheck`, `test:spec`; `test` — what the
|
|
192
|
+
change affects** (`--changed=origin/main`; the full run — CI,
|
|
193
|
+
`docs/testing.md`); before merging — a full build; `set -o pipefail` in
|
|
194
|
+
`script | tail`.
|
|
195
|
+
- **I merge as soon as all checks are green** (the preview deploy too; an
|
|
196
|
+
empty list is "not registered yet") and GitHub merges without a conflict;
|
|
197
|
+
rebase and `--force-with-lease` — only on a textual conflict or my own
|
|
198
|
+
changes. **Before merging — `github pr premerge`:** `main` moved after the
|
|
199
|
+
PR's CI — fast checks on the merge with it; red — I fix the root cause;
|
|
200
|
+
`main` red by itself (exit code 3) — no merge and no fix in the PR: one bug
|
|
201
|
+
for it, I wait for it to close.
|
|
202
|
+
- A merge that deploys — I wait for the deploy on the merge SHA (`ci-wait`),
|
|
203
|
+
the epic refresh in parallel; **then `github task close`**. Others'
|
|
204
|
+
branches, stacks and unmerged work I don't touch.
|
|
205
|
+
- Mechanics — the `github` skill, "Git, PRs and merging — mechanics";
|
|
206
|
+
waiting for checks and deploys — `docs/pr-checks.md`.
|
|
207
|
+
|
|
208
|
+
## Specification — decisions
|
|
209
|
+
|
|
210
|
+
A project's spec is **decisions with a mechanical check**, functional and
|
|
211
|
+
non-functional (a test, a lint rule, an architecture check).
|
|
212
|
+
**No check — no decision; no decision — no code:** behavior without a check
|
|
213
|
+
may change without agreement; code no decision claims is dead. A check is
|
|
214
|
+
written before the code and is red first (acceptance), then holds the
|
|
215
|
+
decision (regression); a decision changes through its check — first the
|
|
216
|
+
check, red, then the code. Three roots of `tests/` by the reader's question:
|
|
217
|
+
`capabilities/<name>` (what the system does), `architecture` (what it's made
|
|
218
|
+
of — a model with checks), `standards/<name>` (code rules, cross-cutting
|
|
219
|
+
qualities); a decision is a folder (`<folder>.md` — why, `<folder>.test.ts` —
|
|
220
|
+
the statements). Exceptions — a mark in the element's file or a file in the
|
|
221
|
+
folder's `exceptions/`, with an `#issue`, a reason and a ratchet. Test names
|
|
222
|
+
are statements in the project language; a code task gets the scenarios
|
|
223
|
+
section (future `it` names) before code. The PR body is `spec-diff` output;
|
|
224
|
+
docs are generated (`spec-doc`) and published by CI to the `spec` branch. A
|
|
225
|
+
recurring decision — a "Standard · …" issue and a rule in `tests/standards/`.
|
|
226
|
+
The full canon and wiring — the `spec` skill (`canon.md`, `checks.md`).
|
|
227
|
+
|
|
228
|
+
## Tests and code
|
|
229
|
+
|
|
230
|
+
- **A test failed — I fix the root cause** (the test or the logic), even if
|
|
231
|
+
unrelated to my changes or a rerun is green — no "pre-existing flake",
|
|
232
|
+
timeouts or retries; a race goes by its cause (the real event, not a
|
|
233
|
+
pause). A flake suspicion — the same run on the base branch: red there too
|
|
234
|
+
— I compare the delta.
|
|
235
|
+
- **A run's result — by the runner's summary**, not the wrapper's exit code.
|
|
236
|
+
Project checks go through the machine queue (the `slot` skill), a full run
|
|
237
|
+
— in the background; e2e and UI in a browser — `docs/testing.md`.
|
|
238
|
+
- **A regression test and a "no defect" guard must be able to fail**: I
|
|
239
|
+
revert the fix, see red, restore it; it didn't fail — it guards against
|
|
240
|
+
overcorrection (named so) or is deleted.
|
|
241
|
+
- **An external API contract — by its schema or docs**, not intuition; on a
|
|
242
|
+
mismatch I fix the test, not the code.
|
|
243
|
+
- **Intentionally different behavior in two places** — mirrored comments
|
|
244
|
+
with the reason.
|
|
245
|
+
- **I check what reached the human** (the delivered email, the page at the
|
|
246
|
+
recipient), not my output; a component on several surfaces — in each.
|
|
247
|
+
- **Judgment:** before a run — which of our mistakes would give the same
|
|
248
|
+
outcome; labels — after checking what the numbers mean; I edit exactly
|
|
249
|
+
what was named; "doesn't reproduce" — with what I measured.
|
|
250
|
+
`docs/judgment.md`.
|
|
251
|
+
|
|
252
|
+
## Production and debugging
|
|
253
|
+
|
|
254
|
+
- **The production database is read-only.** Data and schema change via a
|
|
255
|
+
migration in a PR; DDL on production — only on
|
|
256
|
+
the owner's direct instruction, as a migration file; the environment
|
|
257
|
+
refuses — I explain, no workaround. Data the application manages (roles,
|
|
258
|
+
permissions, audited settings) never changes by direct DML: the audit is
|
|
259
|
+
lost, guards bypassed; what the UI lacks is a code change.
|
|
260
|
+
- **Production numbers — first, is it the right database:** the first query
|
|
261
|
+
checks it against the repository (migrations, columns, orders of
|
|
262
|
+
magnitude); no match — stop.
|
|
263
|
+
- **"Didn't help" → production facts, not a third reproduction:** the logs
|
|
264
|
+
of the real request and production data (the row, `updated_at`, audit),
|
|
265
|
+
then a new hypothesis.
|
|
266
|
+
|
|
267
|
+
## Subagents and worktrees
|
|
268
|
+
|
|
269
|
+
- **Subagents don't share a dirty worktree.** An agent that may install
|
|
270
|
+
packages or touch files "to try" gets an isolated worktree or "read-only
|
|
271
|
+
plus a temp folder" without `git checkout/restore/stash/clean`: its cleanup
|
|
272
|
+
reverts everything uncommitted, others' work too. Several agents in one
|
|
273
|
+
worktree — non-overlapping files, no git, a shared file has one owner. After
|
|
274
|
+
a fan-out — `git status` and `git diff --stat`. Temp files shared with
|
|
275
|
+
subagents get a unique prefix (task, role).
|
|
276
|
+
- **A fresh worktree lacks untracked files** (dependencies, `.env*.local`) —
|
|
277
|
+
I install and copy them. Paths in commands and assignments lead into the
|
|
278
|
+
worktree (a path "from memory" edits `main`); `git -C <worktree> status`
|
|
279
|
+
before and after an edit.
|
|
280
|
+
- **Parallel checkouts share ports, databases and `.git/config`:** the task's
|
|
281
|
+
apps, databases and e2e run in its own Compose stack (the `task-env`
|
|
282
|
+
skill) at `<service>.<N>.<project>.localhost`, not on a host port; others'
|
|
283
|
+
stacks and busy ports I don't touch — `docs/parallel-checkouts.md`.
|
|
284
|
+
- **A subagent gets a unit of ~50 turns** (one decision's folder, one file,
|
|
285
|
+
one spec), not a 200-turn zone: it carries the same preamble (≈ 100k
|
|
286
|
+
tokens), and its price is quadratic in turns. The assignment has the task
|
|
287
|
+
number after the word for "task" or at the start, the epic after the word
|
|
288
|
+
for "epic" ("Language") — so `est` links its work. **Fewer turns:** a file
|
|
289
|
+
in one full read, independent tool calls in one turn.
|
|
290
|
+
|
|
291
|
+
## Project knowledge and handoff
|
|
292
|
+
|
|
293
|
+
- **Shared — in Elves, project-specific — in the project's spec**
|
|
294
|
+
("Specification — decisions"), the reason in the decision's `<folder>.md`;
|
|
295
|
+
neither shared nor checkable (operations, product documents) — the
|
|
296
|
+
project's `docs/`. The project's `AGENTS.md` — the install block and how
|
|
297
|
+
its mode differs. An agreement from chat goes there too, not into the
|
|
298
|
+
agent's memory: memory is a cache, not a source.
|
|
299
|
+
- **I don't revisit the stack** or drag in dependencies; something in the way
|
|
300
|
+
— a question to the user, not a silent replacement. Versions — latest
|
|
301
|
+
stable; a tool question — its official documentation first.
|
|
302
|
+
- **Before a pause or an agent change — a State comment in the issue:** done,
|
|
303
|
+
the branch, next, blockers.
|
|
304
|
+
|
|
305
|
+
## CI: parallel tasks
|
|
306
|
+
|
|
307
|
+
Branches and PRs run in parallel, only my own stale run of a branch is
|
|
308
|
+
cancelled; `main`, tags and manual runs never (`queue: max`); deploy — a
|
|
309
|
+
queue per environment, apart from CI; others' runs I don't cancel or re-run.
|
|
310
|
+
Workflow fragments — `docs/ci-concurrency.md`.
|