changeledger 0.3.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 +25 -0
- package/LICENSE +21 -0
- package/README.md +160 -0
- package/bin/changeledger.mjs +375 -0
- package/package.json +72 -0
- package/src/atomic-write.mjs +134 -0
- package/src/change.mjs +102 -0
- package/src/check.mjs +536 -0
- package/src/commands/agent.mjs +256 -0
- package/src/commands/check.mjs +48 -0
- package/src/commands/graduate.mjs +105 -0
- package/src/commands/init.mjs +43 -0
- package/src/commands/new.mjs +164 -0
- package/src/commands/register.mjs +28 -0
- package/src/commands/release.mjs +138 -0
- package/src/commands/view.mjs +52 -0
- package/src/config.mjs +76 -0
- package/src/contract.mjs +100 -0
- package/src/git.mjs +73 -0
- package/src/lifecycle.mjs +57 -0
- package/src/metrics.mjs +143 -0
- package/src/paths.mjs +12 -0
- package/src/registry.mjs +55 -0
- package/src/release.mjs +71 -0
- package/src/repo.mjs +122 -0
- package/src/slug.mjs +12 -0
- package/src/spec.mjs +12 -0
- package/src/viewer/domain.mjs +133 -0
- package/src/viewer/public/api.js +25 -0
- package/src/viewer/public/app-state.js +87 -0
- package/src/viewer/public/app.js +717 -0
- package/src/viewer/public/index.html +64 -0
- package/src/viewer/public/security.js +65 -0
- package/src/viewer/public/state.js +31 -0
- package/src/viewer/public/styles.css +1062 -0
- package/src/viewer/public/templates.js +9 -0
- package/src/viewer/public/view-parts.js +162 -0
- package/src/viewer/public/view-renderers.js +191 -0
- package/src/viewer/server/router.mjs +200 -0
- package/src/viewer/server/security.mjs +27 -0
- package/src/writer.mjs +151 -0
- package/src/yaml.mjs +75 -0
- package/templates/AGENTS.md +540 -0
- package/templates/config.yml +55 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
# AGENTS.md — ChangeLedger Contract
|
|
2
|
+
|
|
3
|
+
This repo uses **ChangeLedger**. The documents under `.changeledger/` are the **source of
|
|
4
|
+
truth**. Code is their reflection. Work is planned and documented here before any
|
|
5
|
+
code is written.
|
|
6
|
+
|
|
7
|
+
Any agent working in this repo **must** follow this convention.
|
|
8
|
+
|
|
9
|
+
> **Language policy.** Structure is always English; content follows the repo's
|
|
10
|
+
> configured language. See §8.
|
|
11
|
+
|
|
12
|
+
## Agent Fast Path
|
|
13
|
+
|
|
14
|
+
Use this path first; read the detailed sections below when the work touches that
|
|
15
|
+
area.
|
|
16
|
+
|
|
17
|
+
1. Read the repo's own `AGENTS.md`, then this contract at `.changeledger/AGENTS.md`. If the
|
|
18
|
+
link is missing after a clone or move, run `changeledger register`.
|
|
19
|
+
2. Do not create files or implement from a vague request. Create or update a
|
|
20
|
+
change only after the human authorizes documentation.
|
|
21
|
+
3. Do not implement while the change is `draft`. Wait for human approval, then
|
|
22
|
+
commit the approved change document before editing implementation files.
|
|
23
|
+
4. Work one approved change at a time on a non-main branch. Inspect the worktree
|
|
24
|
+
first and keep unrelated changes out of your commits.
|
|
25
|
+
5. Keep the change current as you work: `changeledger status`, `changeledger task`, `changeledger log`, and
|
|
26
|
+
`changeledger owner` are the safest way to update lifecycle, tasks and ownership.
|
|
27
|
+
6. For types that require review, move to `in-review` and delegate a clean-context
|
|
28
|
+
review before human validation. Size any delegated model to the actual
|
|
29
|
+
difficulty; do not over-shard work.
|
|
30
|
+
7. Stop at `in-validation`. The human accepts or rejects the whole result; the
|
|
31
|
+
agent never marks `done`.
|
|
32
|
+
8. After human acceptance, graduate persistent truth into `.changeledger/specs/` or record
|
|
33
|
+
an explicit graduation skip, then archive the done change.
|
|
34
|
+
|
|
35
|
+
When you need exact CLI syntax, run `changeledger help` or `changeledger <command> --help`.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 1. Principles
|
|
40
|
+
|
|
41
|
+
1. Work starts with conversation. Questions and read-only investigation may
|
|
42
|
+
develop the request, but no change file or implementation artifact is created
|
|
43
|
+
until there is enough clarity to document faithfully **and** the human
|
|
44
|
+
explicitly authorizes documentation. A direct request such as “create the
|
|
45
|
+
change” is authorization; if essential information is still missing, clarify
|
|
46
|
+
it instead of inventing requirements.
|
|
47
|
+
2. The human authorizes scope, approves drafts and accepts the final result. The
|
|
48
|
+
agent decides how to divide and execute work within that authorized scope.
|
|
49
|
+
3. Every authorized change is captured as a **change** document before touching
|
|
50
|
+
code.
|
|
51
|
+
4. The document wins. If code and document diverge, the document is the truth:
|
|
52
|
+
update the code, never quietly drift the document.
|
|
53
|
+
5. Humans consume these documents in the **viewer** (`changeledger view`), not as raw
|
|
54
|
+
markdown. Write with the rendered view in mind.
|
|
55
|
+
|
|
56
|
+
## 2. Repo layout
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
.changeledger/
|
|
60
|
+
config.yml # types, active stages, paths, language (repo specifics)
|
|
61
|
+
changes/
|
|
62
|
+
0001-title.md # one change = one file
|
|
63
|
+
specs/ # persistent truth (appears once the first change graduates)
|
|
64
|
+
AGENTS.md # symlink to the installed contract (per-machine, gitignored)
|
|
65
|
+
AGENTS.md # the project's own contract; references .changeledger/AGENTS.md
|
|
66
|
+
CLAUDE.md # optional — same reference, for Claude Code
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Contract discovery.** This contract is a tool artifact, not a project artifact:
|
|
70
|
+
it ships with `changeledger` and is linked into each repo as `.changeledger/AGENTS.md` (a per-machine,
|
|
71
|
+
gitignored symlink — never copied, never committed, so it never drifts). The
|
|
72
|
+
project's own contract files (`AGENTS.md`, and `CLAUDE.md` if present) keep their
|
|
73
|
+
own content; `changeledger init` only appends an alert-box reference pointing agents to
|
|
74
|
+
`.changeledger/AGENTS.md`. `changeledger register` regenerates the link after a clone or move;
|
|
75
|
+
`changeledger check` fails if a reference or the link is missing.
|
|
76
|
+
|
|
77
|
+
## 3. The change
|
|
78
|
+
|
|
79
|
+
A change is **a single markdown file**: frontmatter (structured, for machine and
|
|
80
|
+
viewer) plus a body of **stages** (the lifecycle).
|
|
81
|
+
|
|
82
|
+
### Frontmatter (required)
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
---
|
|
86
|
+
id: "0001"
|
|
87
|
+
title: Short, clear title
|
|
88
|
+
type: feature # feature | bug | audit | refactor | chore
|
|
89
|
+
status: draft # draft | approved | in-progress | in-review | in-validation | blocked | done | discarded
|
|
90
|
+
created: 2026-06-13T13:45:48Z # full ISO 8601 UTC timestamp
|
|
91
|
+
depends_on: [] # ids of other changes, e.g. ["0000"]
|
|
92
|
+
owner: ana # optional — who is working on it (see below)
|
|
93
|
+
release_impact: minor # optional — none | patch | minor | major
|
|
94
|
+
---
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**`owner` (optional).** Who is responsible for the change. It is auto-assigned the
|
|
98
|
+
moment work starts — the `approved → in-progress` transition — unless already set.
|
|
99
|
+
The handle is the **GitHub login** (`gh api user --jq .login`), falling back to
|
|
100
|
+
`git config user.name` when `gh` is missing or unauthenticated. Override or clear
|
|
101
|
+
it anytime with `changeledger owner <id> <name|->`. Absent means unassigned.
|
|
102
|
+
|
|
103
|
+
### Stages (body)
|
|
104
|
+
|
|
105
|
+
Stages are `##` sections with **fixed English headings**. Not every stage applies
|
|
106
|
+
to every type — use only those `config.yml` activates for that `type`. Fixed
|
|
107
|
+
order:
|
|
108
|
+
|
|
109
|
+
| Stage key | `##` heading | Purpose |
|
|
110
|
+
|-----------|--------------|---------|
|
|
111
|
+
| request | `## Request` | What is being asked, context, why. |
|
|
112
|
+
| investigation | `## Investigation` | Findings, current state, constraints, risks. For `bug`: root cause. For `audit`: the core. |
|
|
113
|
+
| proposal | `## Proposal` | Chosen solution + discarded alternatives + scenarios. |
|
|
114
|
+
| specification | `## Specification` | Requirements + acceptance criteria (Given/When/Then). |
|
|
115
|
+
| plan | `## Plan` | Actionable task checklist. |
|
|
116
|
+
| log | `## Log` | Decisions and changes during execution (chronological). |
|
|
117
|
+
|
|
118
|
+
### Active stages per type (defaults)
|
|
119
|
+
|
|
120
|
+
| Type | request | investigation | proposal | specification | plan | log |
|
|
121
|
+
|------|:--:|:--:|:--:|:--:|:--:|:--:|
|
|
122
|
+
| feature | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
123
|
+
| bug | ✓ | ✓ | — | ✓ | ✓ | ✓ |
|
|
124
|
+
| audit | ✓ | ✓ | — | — | — | ✓ |
|
|
125
|
+
| refactor | ✓ | — | ✓ | — | ✓ | ✓ |
|
|
126
|
+
| chore | ✓ | — | — | — | ✓ | — |
|
|
127
|
+
|
|
128
|
+
The real matrix lives in `config.yml`; it can be tuned per repo.
|
|
129
|
+
|
|
130
|
+
### Specification scenarios
|
|
131
|
+
|
|
132
|
+
Acceptance criteria use one **fixed, structured Given/When/Then format** — never
|
|
133
|
+
inline. Each criterion is an `###` block with id `CRn` and a short name, followed
|
|
134
|
+
by per-line steps:
|
|
135
|
+
|
|
136
|
+
```markdown
|
|
137
|
+
### CR1 — Short name
|
|
138
|
+
- **Given** precondition
|
|
139
|
+
- **When** action
|
|
140
|
+
- **Then** expected outcome
|
|
141
|
+
- **And** extra step (optional, repeatable after any Given/When/Then)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
One block per scenario (`CR1`, `CR2`, …). The step keywords (`Given`, `When`,
|
|
145
|
+
`Then`, `And`) are fixed English; the rest is content (per `language`). The
|
|
146
|
+
machine-readable shape is exact: localized headings such as
|
|
147
|
+
`## Especificación`, translated step labels such as `Dado`/`Cuando`/`Entonces`,
|
|
148
|
+
inline criteria, or `#### CR1` do not count as structured criteria for
|
|
149
|
+
`changeledger check`.
|
|
150
|
+
|
|
151
|
+
## 4. Tasks (inside `## Plan`)
|
|
152
|
+
|
|
153
|
+
Markdown checklist. State convention by marker:
|
|
154
|
+
|
|
155
|
+
```markdown
|
|
156
|
+
- [ ] Pending task with target and verification (CR1)
|
|
157
|
+
- [x] Completed task with target and verification (CR1) — 2026-06-13T14:20:00Z
|
|
158
|
+
- [!] Blocked task with target and verification (CR1) — reason for the block
|
|
159
|
+
- [ ] Operational task that changes no observable behavior (support)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The viewer derives progress and the "blocked" state from these markers.
|
|
163
|
+
|
|
164
|
+
**Traceability.** Each task references the criteria it satisfies, in trailing
|
|
165
|
+
parentheses: `- [ ] Validate frontmatter (CR1, CR2)`. This links
|
|
166
|
+
criterion → task, so coverage is auditable. `changeledger check` extracts criteria only
|
|
167
|
+
from the final parenthesized `CRn` block in the task description; mentions of
|
|
168
|
+
`CR1` earlier in the sentence are prose, not traceability.
|
|
169
|
+
|
|
170
|
+
**Machine-readable task grammar.** For tasks that satisfy criteria, keep all
|
|
171
|
+
target and verification text inside the description before the final criteria
|
|
172
|
+
block:
|
|
173
|
+
|
|
174
|
+
```markdown
|
|
175
|
+
- [ ] Update `src/app/foo.ts`; verify: `pnpm test` (CR1)
|
|
176
|
+
- [x] Update `src/app/foo.ts`; verify: `pnpm test` (CR1) — 2026-06-13T14:20:00Z
|
|
177
|
+
- [!] Update `src/app/foo.ts`; verify: `pnpm test` (CR1) — blocked reason
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The trailing `— ...` suffix is reserved for resolution metadata: done timestamps
|
|
181
|
+
and blocked reasons. Pending tasks have no suffix. Do not put readiness evidence
|
|
182
|
+
after the criteria block:
|
|
183
|
+
|
|
184
|
+
```markdown
|
|
185
|
+
- [ ] Update `src/app/foo.ts` (CR1) — verify: `pnpm test`
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
In that bad form, the parser removes `— verify: ...` before readiness checks, so
|
|
189
|
+
the task still references `CR1` but appears to have no verification. Write it as:
|
|
190
|
+
|
|
191
|
+
```markdown
|
|
192
|
+
- [ ] Update `src/app/foo.ts`; verify: `pnpm test` (CR1)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Operational tasks.** Tasks that do not directly satisfy a criterion — running
|
|
196
|
+
a test suite, reading a wrapper before refactoring, evaluating blast radius,
|
|
197
|
+
scaffolding — may carry a literal trailing `(support)` instead of a `CRn`.
|
|
198
|
+
`changeledger check` will not warn about missing criteria for these tasks, and readiness
|
|
199
|
+
checks (target + verification patterns) do not apply to them either. `(support)`
|
|
200
|
+
is not localized and must be the final parenthesized marker. It is not a
|
|
201
|
+
substitute for a missing criterion on an implementation task — if a task writes
|
|
202
|
+
or changes observable behaviour, it must cite the `CRn` it satisfies.
|
|
203
|
+
|
|
204
|
+
**Resolution timestamp.** A completed task (`[x]`) carries a trailing
|
|
205
|
+
`— <ISO 8601 UTC>` with the exact moment it was resolved (full timestamp, so
|
|
206
|
+
same-day tasks keep their order). Pending tasks have none; blocked tasks use the
|
|
207
|
+
suffix for the reason. Order on the line: `description (CRn) — timestamp|reason`.
|
|
208
|
+
|
|
209
|
+
## 5. Lifecycle (`status`)
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
draft → approved → in-progress
|
|
213
|
+
in-progress → in-review → in-validation → done [review required]
|
|
214
|
+
in-progress → in-validation → done [no review required]
|
|
215
|
+
in-review → in-progress [review retry]
|
|
216
|
+
in-review → blocked → in-progress [review escalation]
|
|
217
|
+
in-validation → in-progress [human rejection]
|
|
218
|
+
|
|
219
|
+
(draft | approved | in-progress | blocked) → discarded [terminal]
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- **draft** — created after a human request or authorization. Do not implement yet.
|
|
223
|
+
- **approved** — the human reviewed it in the viewer and approved. Ready to build.
|
|
224
|
+
- **in-progress** — implementation underway; tick tasks as you go.
|
|
225
|
+
- **in-review** — implementation complete; awaiting an **independent review**
|
|
226
|
+
(see §6). Only for types with `review_required: true` in `config.yml`; others
|
|
227
|
+
go straight `in-progress → in-validation`.
|
|
228
|
+
- **in-validation** — implementation and any required independent review are
|
|
229
|
+
complete; the **human** tests and accepts or rejects the change as a whole.
|
|
230
|
+
Acceptance reaches `done`; rejection with a reason returns to `in-progress`.
|
|
231
|
+
- **blocked** — blocked; at least one `[!]` task or external impediment, or a
|
|
232
|
+
review that escalated to a human. Note it in Log.
|
|
233
|
+
- **done** — terminal: all tasks `[x]`, criteria met, required review passed, and
|
|
234
|
+
the human accepted the complete result.
|
|
235
|
+
- **discarded** — a terminal tombstone: the change was decided against. Reachable
|
|
236
|
+
from an active state before the closing gates (not from `done`, `in-review` or
|
|
237
|
+
`in-validation`) via
|
|
238
|
+
`changeledger discard <id> "<reason>"` — the reason is **required** and logged. Prefer
|
|
239
|
+
this over deleting the file: the decision and its rationale stay part of the
|
|
240
|
+
truth, and `depends_on` references keep resolving. Hidden from the board by
|
|
241
|
+
default; revealed by the viewer's "Discarded" toggle. Terminal changes are
|
|
242
|
+
never resurrected; later work gets a new authorized change.
|
|
243
|
+
|
|
244
|
+
**Transitions are enforced.** `changeledger status` validates the graph above; a move
|
|
245
|
+
outside it (e.g. skipping `in-validation`, or reopening a `done`) is rejected.
|
|
246
|
+
`changeledger status` refuses both `done` (human acceptance belongs to the viewer) and
|
|
247
|
+
`discarded` — use the dedicated
|
|
248
|
+
`changeledger discard <id> "<reason>"` so a reason is always captured. The viewer only
|
|
249
|
+
performs the human-owned moves: `draft → approved` and
|
|
250
|
+
`in-validation → done|in-progress`. The agent performs the rest via the CLI.
|
|
251
|
+
After a human-owned move, continue with the existing execution rule: approval
|
|
252
|
+
uses §6.4, rejection uses §6.7, and acceptance uses §6.9 and §10.
|
|
253
|
+
|
|
254
|
+
## 6. Agent rules
|
|
255
|
+
|
|
256
|
+
1. **One concern per change; related work may grow deliberately.** If a request
|
|
257
|
+
mixes unrelated concerns, propose separate changes for human authorization
|
|
258
|
+
(e.g. a bug fix and a new feature). Work necessary to fulfill an active
|
|
259
|
+
change's already authorized objective belongs in that change: update its
|
|
260
|
+
Specification, Plan and Log. If related work materially expands observable
|
|
261
|
+
scope, obtain explicit human authorization before adding it. Independent work
|
|
262
|
+
is proposed as a separate change.
|
|
263
|
+
2. **Do not implement in `draft`.** Create the change, wait for human approval.
|
|
264
|
+
3. **Single source of truth.** Do not duplicate info across stages; link instead.
|
|
265
|
+
4. **Git workflow protects traceability.** Never implement approved changes on
|
|
266
|
+
`main`, `master`, or `dev`; create/switch to a work branch or ask the human
|
|
267
|
+
before continuing. Before implementation, inspect the worktree. If unrelated
|
|
268
|
+
changes exist, do not include them silently: ask whether to stash, commit,
|
|
269
|
+
ignore, or include them. After human approval, commit the approved change
|
|
270
|
+
documentation before touching implementation code. Implement one change at a
|
|
271
|
+
time. Commit a completed unit before continuing when another task, change, or
|
|
272
|
+
modification of the same surface could make attribution ambiguous; do not
|
|
273
|
+
wait until the end to reconstruct mixed diffs. Commit messages reference the
|
|
274
|
+
id, e.g. `feat(scope): description [#0001]`. If shared files make a combined
|
|
275
|
+
commit unavoidable, call it out explicitly in the Log or final response and
|
|
276
|
+
name the changes that share the surface.
|
|
277
|
+
|
|
278
|
+
**Rejected-correction isolation.** After review `fail --retry`, keep the
|
|
279
|
+
candidate correction uncommitted while a fresh clean-context reviewer checks
|
|
280
|
+
it. If review fails again, iterate on the same diff. After `pass`, commit the
|
|
281
|
+
confirmed correction with its related ledger truth before asking for human
|
|
282
|
+
validation.
|
|
283
|
+
|
|
284
|
+
After `in-validation → in-progress`, keep the candidate correction
|
|
285
|
+
uncommitted until the human confirms it fixes the reported failure. Iterate on
|
|
286
|
+
the same diff if it fails again. In either path, do not start another task or
|
|
287
|
+
change while a correction waits, because the worktree is the isolation
|
|
288
|
+
boundary. After human acceptance, graduate/skip and commit the validated
|
|
289
|
+
correction with its related ledger truth. These exceptions prevent false fix
|
|
290
|
+
attempts from becoming permanent history; they do not relax intermediate
|
|
291
|
+
commits for already verified units.
|
|
292
|
+
5. **Keep the change updated as you go:** tick tasks, move `status`, write to Log.
|
|
293
|
+
The document reflects reality at all times.
|
|
294
|
+
6. **Independent review when configured.** When the implementation is complete,
|
|
295
|
+
move to `in-review` and **delegate the review to a fresh subagent** — clean
|
|
296
|
+
context (no implementation history, so no bias) and a model **sized to the
|
|
297
|
+
difficulty** (don't spend a costly model on a trivial check). The reviewer
|
|
298
|
+
verifies: every `CRn` is met, no residue (rule 8), and the Plan is truly done.
|
|
299
|
+
Deep security/SAST/lint live in
|
|
300
|
+
dedicated tools — the reviewer may invoke them and record the verdict, but
|
|
301
|
+
ChangeLedger does not reimplement them. Record the verdict with `changeledger review` (§9):
|
|
302
|
+
`pass → in-validation`; `fail --retry` (defect inside the contract → back to
|
|
303
|
+
`in-progress`); `fail --block` (exceeds the contract → `blocked` for a human).
|
|
304
|
+
*How* the subagent is spawned is the host agent's concern; the contract only
|
|
305
|
+
fixes that it must be a clean-context subagent. Types without
|
|
306
|
+
`review_required` move directly from `in-progress` to `in-validation`.
|
|
307
|
+
7. **Human validation before `done`.** The agent stops at `in-validation` and
|
|
308
|
+
asks the human to test the complete result in the viewer. The agent never
|
|
309
|
+
accepts on the human's behalf. A rejection requires a reason and returns the
|
|
310
|
+
same change to `in-progress`; update its Specification/Plan and add ordinary
|
|
311
|
+
tasks as needed, then repeat review (when configured) and validation. `done`
|
|
312
|
+
and `discarded` never reopen.
|
|
313
|
+
8. **No residue:** no TODO/FIXME or dead code without explicit agreement.
|
|
314
|
+
9. **On completion**, graduate the truth: update or create the `specs/` doc(s)
|
|
315
|
+
that capture the new persistent state (see §10).
|
|
316
|
+
10. **Prefer visuals.** When a diagram explains something better than prose
|
|
317
|
+
(flows, state, architecture, relationships), use a ` ```mermaid ` block. The
|
|
318
|
+
diagram text is the source; the viewer renders it. Humans grasp it faster.
|
|
319
|
+
11. **Delegation is the agent's call, but it must be economical.** ChangeLedger is
|
|
320
|
+
agnostic to *how* work gets done: any stage may be delegated to subagents at
|
|
321
|
+
the host agent's discretion, and the contract never prescribes the mechanism
|
|
322
|
+
(that is the agent's and harness's responsibility). Delegation is expected
|
|
323
|
+
when it reduces main-context pressure, lowers cost with a sufficient model,
|
|
324
|
+
parallelizes genuinely independent work, or provides clean-context review.
|
|
325
|
+
It is wasteful when it multiplies coordination without improving quality,
|
|
326
|
+
speed, or context control.
|
|
327
|
+
|
|
328
|
+
**Delegate for a reason.** Good delegation units have a clear question or
|
|
329
|
+
ownership boundary: an investigation surface, a module, a package, a test
|
|
330
|
+
area, a migration slice, or an independent verification. Request and
|
|
331
|
+
Investigation may split independent codebase questions across explorers.
|
|
332
|
+
Proposal and Specification may use a stronger model when ambiguity,
|
|
333
|
+
architecture, safety, or product judgment is high. Implementation may split
|
|
334
|
+
across workers only when write sets are disjoint and integration is obvious.
|
|
335
|
+
Verification may be delegated when it catches risk without duplicating the
|
|
336
|
+
implementer's work. Review (§6.6) is special: for configured types,
|
|
337
|
+
delegation to a **clean-context** subagent is a *contract requirement* —
|
|
338
|
+
there, independence is correctness, not an optimization.
|
|
339
|
+
|
|
340
|
+
**Do not over-shard.** Do not create one subagent per file, per line, or per
|
|
341
|
+
tiny mechanical edit. If many files need the same small change, prefer one
|
|
342
|
+
well-scoped subagent, a batch edit, or a script that the main agent verifies.
|
|
343
|
+
Do not run parallel subagents over the same files or conceptual surface
|
|
344
|
+
unless the overlap is deliberate and the integration plan is explicit. If
|
|
345
|
+
the main agent cannot state why a subtask is independent, what output it
|
|
346
|
+
expects, and how it will integrate the result, keep the work in the main
|
|
347
|
+
thread or regroup it.
|
|
348
|
+
|
|
349
|
+
**Size the model to the task.** Use the strongest available models for
|
|
350
|
+
ambiguous scope, architectural tradeoffs, security-sensitive reasoning,
|
|
351
|
+
complex specification, and difficult reviews. Use sufficient cheaper models
|
|
352
|
+
for localized exploration, inventories, straightforward implementation,
|
|
353
|
+
mechanical edits, running tests, and checking narrow hypotheses. Escalate
|
|
354
|
+
model strength when uncertainty or risk rises; de-escalate when the task is
|
|
355
|
+
already specified and mostly execution.
|
|
356
|
+
|
|
357
|
+
**Every delegation prompt names the contract.** State the reason for
|
|
358
|
+
delegating, the owned files/area or investigation question, the expected
|
|
359
|
+
output, the model-sized difficulty if relevant, and the integration
|
|
360
|
+
criterion. Tell coding subagents that they are not alone in the codebase:
|
|
361
|
+
they must not revert others' edits, and they must keep changes inside their
|
|
362
|
+
assigned ownership.
|
|
363
|
+
12. **Triage friction at handoff; retrospect after completion.** Before handing
|
|
364
|
+
the human a completed or blocked work result, review any friction, ambiguity,
|
|
365
|
+
bug, or improvement already discovered while using ChangeLedger, then
|
|
366
|
+
classify it:
|
|
367
|
+
- If it is necessary to fulfill the purpose of an active change, update that
|
|
368
|
+
change's Specification/Plan/Log; do not create another.
|
|
369
|
+
- If it is an operational step of the current flow (verify, commit, graduate,
|
|
370
|
+
archive, close), execute or record it in the current change; it is not a
|
|
371
|
+
new change.
|
|
372
|
+
- If it is independent, too large, or materially expands impact, propose its
|
|
373
|
+
type, title, and reason to the human. Create the draft only after explicit
|
|
374
|
+
authorization; a direct request such as “create the change” is already
|
|
375
|
+
authorization. Batch proposals at the end of the turn when practical.
|
|
376
|
+
- If it is too vague for backlog, mention it without creating a file.
|
|
377
|
+
|
|
378
|
+
This triage must not mix independent concerns into active work or block work
|
|
379
|
+
that is otherwise ready for validation. When a change reaches `done`, also
|
|
380
|
+
share a brief retrospective of the completed cycle with the human. A
|
|
381
|
+
`discarded` change records why it was decided against but does not imply a
|
|
382
|
+
completed implementation cycle.
|
|
383
|
+
|
|
384
|
+
## 7. IDs
|
|
385
|
+
|
|
386
|
+
The `id` is the UTC creation instant in `YYYYMMDD-HHMMSS` form, derived from
|
|
387
|
+
`created` (one instant, one source). Example: `created: 2026-06-13T15:04:02Z` →
|
|
388
|
+
`id: "20260613-150402"`. Filename is `{id}-{slug}.md`, e.g.
|
|
389
|
+
`20260613-150402-timestamp-ids.md`.
|
|
390
|
+
|
|
391
|
+
Timestamp ids are unique without central coordination, so concurrent
|
|
392
|
+
devs/agents on parallel branches never collide. They sort chronologically. The
|
|
393
|
+
viewer may display an abbreviated form (`#0613-1504`); the full id is canonical.
|
|
394
|
+
|
|
395
|
+
The `{slug}` is **always English** (it is part of the filename — structure, not
|
|
396
|
+
content; see §8), even when the change content is in another language. `changeledger new`
|
|
397
|
+
takes it explicitly: `changeledger new <type> <slug> "<title>"`.
|
|
398
|
+
|
|
399
|
+
## 8. Language policy
|
|
400
|
+
|
|
401
|
+
| Always English (fixed) | Variable (per `config.yml` `language`) |
|
|
402
|
+
|------------------------|----------------------------------------|
|
|
403
|
+
| frontmatter keys (`id`, `type`, `status`, …) | `title` value (it is change content) |
|
|
404
|
+
| enum values: `status`, `type` | prose inside each stage |
|
|
405
|
+
| stage keys and headings (`## Request`, …) | human narrative (README, etc.) |
|
|
406
|
+
| acceptance ids and step keywords (`CR1`, `Given`, `When`, `Then`, `And`) | scenario content after the keyword |
|
|
407
|
+
| task markers and structural markers (`- [ ]`, `(CR1)`, `(support)`) | task prose |
|
|
408
|
+
| file/dir names, CLI | |
|
|
409
|
+
|
|
410
|
+
This contract is the canonical spec and stays in English regardless of the
|
|
411
|
+
repo's configured language.
|
|
412
|
+
|
|
413
|
+
## 9. Optional CLI helpers
|
|
414
|
+
|
|
415
|
+
Files are the source of truth; you may edit them directly. But the CLI does the
|
|
416
|
+
error-prone parts (UTC timestamps, status enums, task markers) for you. Run
|
|
417
|
+
`changeledger help` for the full list and `changeledger <command> --help` for exact options.
|
|
418
|
+
|
|
419
|
+
Critical flow commands:
|
|
420
|
+
|
|
421
|
+
- `changeledger register` — relink this repo's path and `.changeledger/AGENTS.md` after a move/clone.
|
|
422
|
+
- `changeledger new <type> <slug> "<title>"` — scaffold a change; the slug is English.
|
|
423
|
+
- `changeledger status <id> <status>` — move the lifecycle and log the transition. It does
|
|
424
|
+
not accept `done` (the human accepts in the viewer) or `discarded` (use
|
|
425
|
+
`changeledger discard <id> "<reason>"`); see §5.
|
|
426
|
+
- `changeledger task <id> done|block <n> [reason]` — mark a Plan task; `done` injects UTC.
|
|
427
|
+
- `changeledger log <id> "<message>"` and `changeledger owner <id> <name|->` — keep execution notes
|
|
428
|
+
and ownership current.
|
|
429
|
+
- `changeledger review <id> pass` — record a passed independent review
|
|
430
|
+
(`in-review → in-validation`).
|
|
431
|
+
- `changeledger review <id> fail --retry|--block "<reason>"` — route review failure back
|
|
432
|
+
to `in-progress` (fixable) or `blocked` (escalates to a human).
|
|
433
|
+
- `changeledger check [id]` — validate a change or the whole repo before committing.
|
|
434
|
+
|
|
435
|
+
Closing and persistence commands:
|
|
436
|
+
|
|
437
|
+
- `changeledger graduate <change-id> <spec-slug>` — scaffold a **new** spec seeded from the change.
|
|
438
|
+
- `changeledger graduate <change-id> <spec-slug> --into` — graduate into an **existing**
|
|
439
|
+
spec: refresh its `updated`, link it in the change Log and mark `reviewed`,
|
|
440
|
+
without overwriting the spec body (the agent edits the body manually).
|
|
441
|
+
- `changeledger graduate <change-id> --skip [reason]` — mark a done change's graduation
|
|
442
|
+
reviewed without a spec (bug/chore with no persistent truth); logs the reason.
|
|
443
|
+
- `changeledger graduate --pending` — list done changes whose graduation is not reviewed yet.
|
|
444
|
+
- `changeledger archive <id>` / `changeledger unarchive <id>` — hide/show a change in the viewer.
|
|
445
|
+
- `changeledger list [--status S] [--type T] [--json]` / `changeledger show <id> [--json]` — inspect
|
|
446
|
+
state without manually parsing files.
|
|
447
|
+
|
|
448
|
+
Release commands:
|
|
449
|
+
|
|
450
|
+
- `changeledger release init <version>` — adopt release tracking at an existing stable
|
|
451
|
+
SemVer version; the baseline includes all changes already `done`.
|
|
452
|
+
- `changeledger release plan [--json]` — calculate the next version and included changes
|
|
453
|
+
without writing. JSON is the handoff contract for the operating agent.
|
|
454
|
+
- `changeledger release record <version>` — record the exactly calculated release in
|
|
455
|
+
`.changeledger/releases/<version>.yml`; it does not edit stack manifests or perform Git,
|
|
456
|
+
hosting or publishing operations.
|
|
457
|
+
|
|
458
|
+
### Release boundary
|
|
459
|
+
|
|
460
|
+
Release impact defaults live under `release.impacts` in `.changeledger/config.yml` and a
|
|
461
|
+
change may override its type with `release_impact`. ChangeLedger owns the
|
|
462
|
+
portable decision: which completed changes ship and what stable SemVer follows.
|
|
463
|
+
The operating agent owns technology-specific application and delivery: update
|
|
464
|
+
`package.json`, `pubspec.yaml`, `Cargo.toml`, Gradle, Xcode or monorepo surfaces;
|
|
465
|
+
run the project gates; then commit, tag and publish according to the local
|
|
466
|
+
contract. Never infer that every ChangeLedger repository uses npm or GitHub.
|
|
467
|
+
|
|
468
|
+
## 10. Specs (persistent truth)
|
|
469
|
+
|
|
470
|
+
`changes/` are deltas with a lifecycle; `.changeledger/specs/*.md` are the **persistent
|
|
471
|
+
truth** — the current state of the system (capabilities, architecture, domain).
|
|
472
|
+
Code reflects the specs.
|
|
473
|
+
|
|
474
|
+
Specs have **no lifecycle** (no `status`). Minimal frontmatter, free markdown
|
|
475
|
+
body (headings are not stages):
|
|
476
|
+
|
|
477
|
+
```yaml
|
|
478
|
+
---
|
|
479
|
+
title: Short title
|
|
480
|
+
updated: 2026-06-13T21:00:00Z # ISO 8601 UTC
|
|
481
|
+
tags: []
|
|
482
|
+
---
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
When a change reaches `done`, update or create the spec(s) it affects. A change
|
|
486
|
+
is the journey; a spec is the destination. `changeledger graduate <change-id> <spec-slug>`
|
|
487
|
+
scaffolds a **new** spec seeded from the change's Specification/Proposal and links
|
|
488
|
+
it back in the change's Log — then refine the wording by hand. To graduate into an
|
|
489
|
+
**existing** spec (the common case — extending `architecture.md` etc.), use
|
|
490
|
+
`--into`: it links and marks `reviewed` and refreshes the spec's `updated` without
|
|
491
|
+
overwriting the body, which you edit. Prefer diagrams (§6.10 / mermaid) where they
|
|
492
|
+
explain the system better than prose.
|
|
493
|
+
|
|
494
|
+
**Graduation review.** A done change either graduates to a spec or is reviewed as
|
|
495
|
+
needing none (a bug/chore with no persistent truth). Both set the optional
|
|
496
|
+
`reviewed: true` frontmatter flag. `changeledger graduate --pending` lists done changes
|
|
497
|
+
still unreviewed; resolve each with `changeledger graduate <id> <spec>` or
|
|
498
|
+
`changeledger graduate <id> --skip [reason]`. ("graduated to a spec" stays derivable from
|
|
499
|
+
the `graduado a spec` Log marker; `reviewed` only tracks that the question is
|
|
500
|
+
settled.)
|
|
501
|
+
|
|
502
|
+
## 11. Definition of Ready (implementation)
|
|
503
|
+
|
|
504
|
+
ChangeLedger is built for a split: a **strong model documents**, a **less capable
|
|
505
|
+
(but able) model implements**. So a change must carry enough that the implementer
|
|
506
|
+
needs no extra reasoning. The `tdd` flag in `config.yml` governs this (default
|
|
507
|
+
`true`); set it `false` only for exploratory repos. Repos may tune the concrete
|
|
508
|
+
shape with `readiness.target_patterns` and `readiness.verification_patterns`
|
|
509
|
+
(for example `src/**` + `test/**`, colocated `**/*.spec.ts`, or verification
|
|
510
|
+
commands such as `pnpm test`). For repos with manual/device verification,
|
|
511
|
+
prefer a structural convention such as `verification_patterns: ["verify:"]` and
|
|
512
|
+
write the concrete evidence in the task (`verify: manual Android device check`)
|
|
513
|
+
instead of listing every possible manual phrase in config.
|
|
514
|
+
|
|
515
|
+
When `tdd: true`, a change is **ready to implement** when:
|
|
516
|
+
|
|
517
|
+
1. **Specification is test-grade.** Every behavioral requirement is a `CRn` with
|
|
518
|
+
**concrete values** (the actual input, not "a valid input"), the expected
|
|
519
|
+
output/effect, and **literal** error messages. Each edge case is its own `CR`.
|
|
520
|
+
No requirement lives only in prose — if it must hold, it is a `CR`.
|
|
521
|
+
2. **Plan is the implementation contract.** Every task references ≥1 `CR`, names
|
|
522
|
+
the **target file(s)/area(s)** and the **verification** *in its description*
|
|
523
|
+
according to the repo's readiness patterns, and is sized to one red-green
|
|
524
|
+
cycle. The description is the part before the final `(CRn)` block and before
|
|
525
|
+
any trailing `— ...` resolution suffix (see §4), so readiness evidence such as
|
|
526
|
+
`verify:` must appear before `(CRn)`. The verification can be a test file next
|
|
527
|
+
to the target, a conventional test directory, or a concrete command when that
|
|
528
|
+
is how the repo proves the behavior. Pure support tasks (docs, scaffolding)
|
|
529
|
+
may carry no `CR` — `changeledger check` will note them so the author confirms the
|
|
530
|
+
omission is intentional.
|
|
531
|
+
3. **TDD is explicit.** The implementer writes the failing test from the `CR`,
|
|
532
|
+
makes it pass, then refactors. The implementer never decides *what* to test —
|
|
533
|
+
the `CR` fixes that; only *how*.
|
|
534
|
+
|
|
535
|
+
`changeledger check` enforces this lightly: for a change whose type activates
|
|
536
|
+
`## Specification`, it reports readiness gaps (`draft` as warnings,
|
|
537
|
+
`approved`/`in-progress` as errors) when a `CR` has no covering task, a task
|
|
538
|
+
references no `CR`, a task references an unknown `CR`, a criterion is missing
|
|
539
|
+
Given/When/Then, or a CR-bearing task does not name both target and verification
|
|
540
|
+
according to the repo's readiness patterns.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# ChangeLedger — repo configuration
|
|
2
|
+
# Repo specifics: documentation language, change types and active stages per type.
|
|
3
|
+
|
|
4
|
+
# Language for generated documentation CONTENT. Structure (headings, keys, enums)
|
|
5
|
+
# is always English. See AGENTS.md §8.
|
|
6
|
+
language: en
|
|
7
|
+
|
|
8
|
+
# Definition of Ready policy. When true (default), changes are documented
|
|
9
|
+
# test-grade and implemented via TDD; `changeledger check` warns on criteria ↔ task
|
|
10
|
+
# coverage gaps. Set false for exploratory repos. See AGENTS.md §11.
|
|
11
|
+
tdd: true
|
|
12
|
+
|
|
13
|
+
# Default SemVer impact for a completed change. A change may override its type
|
|
14
|
+
# with `release_impact: none|patch|minor|major` in frontmatter.
|
|
15
|
+
release:
|
|
16
|
+
impacts:
|
|
17
|
+
feature: minor
|
|
18
|
+
bug: patch
|
|
19
|
+
audit: none
|
|
20
|
+
refactor: none
|
|
21
|
+
chore: none
|
|
22
|
+
|
|
23
|
+
# Optional Definition of Ready path/command hints. When present, tasks that
|
|
24
|
+
# reference CRs should name at least one target and one verification matching
|
|
25
|
+
# these patterns. Patterns can be path globs or literal command snippets.
|
|
26
|
+
# readiness:
|
|
27
|
+
# target_patterns: ["src/**"]
|
|
28
|
+
# verification_patterns: ["test/**", "**/*.test.*", "**/*.spec.*", "pnpm test"]
|
|
29
|
+
|
|
30
|
+
changes_dir: .changeledger/changes
|
|
31
|
+
specs_dir: .changeledger/specs
|
|
32
|
+
|
|
33
|
+
# Valid lifecycle statuses (order = progress)
|
|
34
|
+
statuses: [draft, approved, in-progress, in-review, in-validation, blocked, done, discarded]
|
|
35
|
+
|
|
36
|
+
# Canonical stages (## headings in the change body)
|
|
37
|
+
stages: [request, investigation, proposal, specification, plan, log]
|
|
38
|
+
|
|
39
|
+
# Active stages per type. The viewer shows only these.
|
|
40
|
+
# `review_required: true` makes the change pass through `in-review` (an
|
|
41
|
+
# independent subagent review) before universal human validation. See AGENTS.md §5/§6.
|
|
42
|
+
types:
|
|
43
|
+
feature:
|
|
44
|
+
stages: [request, investigation, proposal, specification, plan, log]
|
|
45
|
+
review_required: true
|
|
46
|
+
bug:
|
|
47
|
+
stages: [request, investigation, specification, plan, log]
|
|
48
|
+
review_required: true
|
|
49
|
+
audit:
|
|
50
|
+
stages: [request, investigation, log]
|
|
51
|
+
refactor:
|
|
52
|
+
stages: [request, proposal, plan, log]
|
|
53
|
+
review_required: true
|
|
54
|
+
chore:
|
|
55
|
+
stages: [request, plan]
|