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.
Files changed (44) hide show
  1. package/AGENTS.md +25 -0
  2. package/LICENSE +21 -0
  3. package/README.md +160 -0
  4. package/bin/changeledger.mjs +375 -0
  5. package/package.json +72 -0
  6. package/src/atomic-write.mjs +134 -0
  7. package/src/change.mjs +102 -0
  8. package/src/check.mjs +536 -0
  9. package/src/commands/agent.mjs +256 -0
  10. package/src/commands/check.mjs +48 -0
  11. package/src/commands/graduate.mjs +105 -0
  12. package/src/commands/init.mjs +43 -0
  13. package/src/commands/new.mjs +164 -0
  14. package/src/commands/register.mjs +28 -0
  15. package/src/commands/release.mjs +138 -0
  16. package/src/commands/view.mjs +52 -0
  17. package/src/config.mjs +76 -0
  18. package/src/contract.mjs +100 -0
  19. package/src/git.mjs +73 -0
  20. package/src/lifecycle.mjs +57 -0
  21. package/src/metrics.mjs +143 -0
  22. package/src/paths.mjs +12 -0
  23. package/src/registry.mjs +55 -0
  24. package/src/release.mjs +71 -0
  25. package/src/repo.mjs +122 -0
  26. package/src/slug.mjs +12 -0
  27. package/src/spec.mjs +12 -0
  28. package/src/viewer/domain.mjs +133 -0
  29. package/src/viewer/public/api.js +25 -0
  30. package/src/viewer/public/app-state.js +87 -0
  31. package/src/viewer/public/app.js +717 -0
  32. package/src/viewer/public/index.html +64 -0
  33. package/src/viewer/public/security.js +65 -0
  34. package/src/viewer/public/state.js +31 -0
  35. package/src/viewer/public/styles.css +1062 -0
  36. package/src/viewer/public/templates.js +9 -0
  37. package/src/viewer/public/view-parts.js +162 -0
  38. package/src/viewer/public/view-renderers.js +191 -0
  39. package/src/viewer/server/router.mjs +200 -0
  40. package/src/viewer/server/security.mjs +27 -0
  41. package/src/writer.mjs +151 -0
  42. package/src/yaml.mjs +75 -0
  43. package/templates/AGENTS.md +540 -0
  44. 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]