changeledger 0.4.0 → 0.5.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 +13 -7
- package/README.md +22 -13
- package/bin/changeledger.mjs +10 -2
- package/package.json +1 -1
- package/src/commands/agent.mjs +1 -1
- package/src/commands/check.mjs +1 -1
- package/src/commands/context.mjs +65 -0
- package/src/commands/init.mjs +3 -6
- package/src/commands/new.mjs +1 -1
- package/src/commands/register.mjs +10 -6
- package/src/contract.mjs +86 -50
- package/src/paths.mjs +1 -1
- package/src/viewer/public/app.js +32 -2
- package/templates/config.yml +4 -3
- package/templates/contract/blocked.md +6 -0
- package/templates/contract/close.md +18 -0
- package/templates/contract/core.md +64 -0
- package/templates/contract/discarded.md +5 -0
- package/templates/contract/implement.md +52 -0
- package/templates/contract/readiness.md +19 -0
- package/templates/contract/release.md +15 -0
- package/templates/contract/review.md +19 -0
- package/templates/contract/spec.md +94 -0
- package/templates/contract/validation.md +9 -0
- package/templates/AGENTS.md +0 -540
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ChangeLedger — Core Contract
|
|
2
|
+
|
|
3
|
+
Documents under `.changeledger/` are the source of truth. Code is their
|
|
4
|
+
reflection. Work is planned and documented before code is written.
|
|
5
|
+
|
|
6
|
+
## Non-negotiable fast path
|
|
7
|
+
|
|
8
|
+
1. Work starts with conversation. Read-only investigation may clarify a request,
|
|
9
|
+
but create no change or implementation artifact until there is enough clarity
|
|
10
|
+
to document faithfully **and** the human explicitly authorizes documentation. A direct request such
|
|
11
|
+
as “create the change” is authorization; never invent missing requirements.
|
|
12
|
+
2. The human authorizes scope, approves drafts and accepts the final result. The
|
|
13
|
+
agent decides how to divide and execute work within that authorized scope.
|
|
14
|
+
3. Capture every authorized change in `.changeledger/changes/`. The document
|
|
15
|
+
wins when code and documentation disagree.
|
|
16
|
+
4. Never implement a `draft`. After approval, work one change at a time on a
|
|
17
|
+
non-main branch and commit the approved change document before code.
|
|
18
|
+
5. Keep lifecycle, tasks, ownership and Log current while working.
|
|
19
|
+
6. For types that require review, use a fresh clean-context reviewer before
|
|
20
|
+
human validation.
|
|
21
|
+
7. Stop at `in-validation`. The agent never accepts on the human's behalf.
|
|
22
|
+
8. After human acceptance, graduate persistent truth or record an explicit skip,
|
|
23
|
+
then archive the done change.
|
|
24
|
+
|
|
25
|
+
Humans consume changes in `changeledger view`; write for the rendered view.
|
|
26
|
+
|
|
27
|
+
## Lifecycle
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
draft → approved → in-progress
|
|
31
|
+
in-progress → in-review → in-validation → done [review required]
|
|
32
|
+
in-progress → in-validation → done [no review required]
|
|
33
|
+
in-review → in-progress [review retry]
|
|
34
|
+
in-review → blocked → in-progress [review escalation]
|
|
35
|
+
in-validation → in-progress [human rejection]
|
|
36
|
+
(draft | approved | in-progress | blocked) → discarded
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- `draft`: documentation awaiting human approval; no implementation.
|
|
40
|
+
- `approved`: ready to start after the Git/worktree checks.
|
|
41
|
+
- `in-progress`: implementation underway.
|
|
42
|
+
- `in-review`: independent review required.
|
|
43
|
+
- `in-validation`: stop and wait for human acceptance or rejection.
|
|
44
|
+
- `blocked`: an impediment or decision needs resolution.
|
|
45
|
+
- `done`: terminal; the human accepted the complete result.
|
|
46
|
+
- `discarded`: terminal tombstone; never reopen it.
|
|
47
|
+
|
|
48
|
+
`changeledger status <id> <status>` enforces agent-owned transitions and does not accept `done` or `discarded`.
|
|
49
|
+
Humans approve and validate in the viewer; use
|
|
50
|
+
`changeledger discard <id> "<reason>"` for a discarded change. `done` and `discarded`
|
|
51
|
+
never reopen.
|
|
52
|
+
|
|
53
|
+
## Context modes
|
|
54
|
+
|
|
55
|
+
Valid modes: implement, review, spec, release.
|
|
56
|
+
|
|
57
|
+
- `changeledger context spec`: author or refine a change.
|
|
58
|
+
- `changeledger context implement`: execute an approved change.
|
|
59
|
+
- `changeledger context review`: independently verify completed work.
|
|
60
|
+
- `changeledger context release`: plan portable delivery metadata.
|
|
61
|
+
- `changeledger context <change-id>`: infer the correct context from lifecycle.
|
|
62
|
+
|
|
63
|
+
Run `changeledger help` or `changeledger <command> --help` for exact CLI syntax.
|
|
64
|
+
Structure is always English; narrative content follows `.changeledger/config.yml`.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Implementing an Approved Change
|
|
2
|
+
|
|
3
|
+
1. Keep one concern per change. Work necessary for the authorized objective may
|
|
4
|
+
update Specification, Plan and Log. If related work materially expands observable scope, obtain explicit human
|
|
5
|
+
authorization before adding it; propose independent work separately.
|
|
6
|
+
2. Never implement approved changes on `main`, `master`, or `dev`. Inspect the
|
|
7
|
+
worktree first. If unrelated changes exist, do not include them silently.
|
|
8
|
+
3. Commit the approved change documentation before touching implementation code.
|
|
9
|
+
Implement one change at a time.
|
|
10
|
+
4. Commit a completed unit before continuing when another task or shared edit makes attribution
|
|
11
|
+
ambiguous. Commit messages reference the id. If shared files make a combined commit
|
|
12
|
+
unavoidable, record it explicitly and name every change sharing the surface.
|
|
13
|
+
5. Keep the change current with `changeledger task`, `changeledger log`,
|
|
14
|
+
`changeledger owner` and `changeledger status`.
|
|
15
|
+
6. Follow the Specification exactly. Write a failing test from each criterion,
|
|
16
|
+
make it pass, then refactor. Do not silently drift the document.
|
|
17
|
+
7. Leave no TODO/FIXME, dead code or unrelated residue without explicit agreement.
|
|
18
|
+
8. When implementation and tasks are complete, move to `in-review` if the type
|
|
19
|
+
requires independent review; otherwise move to `in-validation` and stop.
|
|
20
|
+
|
|
21
|
+
## Correction isolation
|
|
22
|
+
|
|
23
|
+
After review `fail --retry`, keep the candidate correction uncommitted while a
|
|
24
|
+
fresh clean-context reviewer checks it. If it fails again, iterate on that diff.
|
|
25
|
+
After `pass`, commit the confirmed correction and ledger truth before asking for
|
|
26
|
+
human validation.
|
|
27
|
+
|
|
28
|
+
After human rejection (`in-validation → in-progress`), keep the correction
|
|
29
|
+
uncommitted until the human confirms it. Do not start another task or change
|
|
30
|
+
while a correction waits; the worktree is the isolation boundary.
|
|
31
|
+
|
|
32
|
+
## Triage friction at handoff; retrospect after completion
|
|
33
|
+
|
|
34
|
+
Before handing the human completed or blocked work, classify discovered
|
|
35
|
+
friction:
|
|
36
|
+
|
|
37
|
+
- If necessary to fulfill the purpose of an active change, update that change.
|
|
38
|
+
- If it is an operational step such as verify, commit, graduate or archive,
|
|
39
|
+
execute or record it in the current flow.
|
|
40
|
+
- If independent or materially larger, propose its type, title, and reason to
|
|
41
|
+
the human. Create the draft only after explicit authorization.
|
|
42
|
+
- If too vague for backlog, mention it without creating a file.
|
|
43
|
+
|
|
44
|
+
When a change reaches `done`, also share a brief retrospective with the human.
|
|
45
|
+
|
|
46
|
+
## Useful commands
|
|
47
|
+
|
|
48
|
+
- `changeledger status <id> <status>`
|
|
49
|
+
- `changeledger task <id> done|block <n> [reason]`
|
|
50
|
+
- `changeledger log <id> "<message>"`
|
|
51
|
+
- `changeledger owner <id> <name|->`
|
|
52
|
+
- `changeledger check [id]`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Definition of Ready
|
|
2
|
+
|
|
3
|
+
With `tdd: true`, an approved change is ready only when:
|
|
4
|
+
|
|
5
|
+
1. Every behavioral requirement is a concrete `CRn` with actual inputs, exact
|
|
6
|
+
outputs/effects and literal errors. Edge cases get separate criteria.
|
|
7
|
+
2. Every implementation task names target file(s)/area(s), verification, and the
|
|
8
|
+
criteria it satisfies. It is sized to one red-green cycle.
|
|
9
|
+
3. TDD is explicit: write the failing test from the criterion, make it pass, then
|
|
10
|
+
refactor. The implementer chooses how, not what, to test.
|
|
11
|
+
|
|
12
|
+
Repos may configure `readiness.target_patterns` and
|
|
13
|
+
`readiness.verification_patterns`. For manual checks, prefer a structural rule
|
|
14
|
+
such as `verification_patterns: ["verify:"]`, then write evidence like
|
|
15
|
+
`verify: manual Android device check` instead of listing every possible manual phrase.
|
|
16
|
+
|
|
17
|
+
`changeledger check` reports missing Given/When/Then, uncovered or unknown CRs,
|
|
18
|
+
tasks without traceability, and CR-bearing tasks without a configured target and
|
|
19
|
+
verification (`draft` warnings; approved/in-progress errors).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Portable Release Planning
|
|
2
|
+
|
|
3
|
+
- `changeledger release init <version>` adopts release tracking at an existing
|
|
4
|
+
stable SemVer; the baseline contains changes already done.
|
|
5
|
+
- `changeledger release plan [--json]` deterministically selects unreleased done
|
|
6
|
+
changes and calculates the next version without writing.
|
|
7
|
+
- `changeledger release record <version>` records exactly that plan in
|
|
8
|
+
`.changeledger/releases/<version>.yml`.
|
|
9
|
+
|
|
10
|
+
Defaults live under `release.impacts` in `.changeledger/config.yml`; a change may
|
|
11
|
+
override its type with `release_impact` (`none|patch|minor|major`).
|
|
12
|
+
|
|
13
|
+
ChangeLedger owns portable membership and SemVer. The operating agent owns
|
|
14
|
+
stack-specific version files, project gates, commits, tags and publishing.
|
|
15
|
+
Never infer that every ChangeLedger repository uses npm or GitHub.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Independent Review
|
|
2
|
+
|
|
3
|
+
Review-required work must be checked by a fresh subagent with clean context and
|
|
4
|
+
a model sized to the difficulty. Independence is correctness, not an
|
|
5
|
+
optimization. The reviewer verifies every criterion, every Plan task, tests,
|
|
6
|
+
the actual diff and absence of residue; it does not trust the implementer's
|
|
7
|
+
summary.
|
|
8
|
+
|
|
9
|
+
Delegate for a clear reason and boundary. Do not over-shard by file or tiny edit,
|
|
10
|
+
and do not overlap write surfaces without an explicit integration plan.
|
|
11
|
+
|
|
12
|
+
- Pass: `changeledger review <id> pass` → `in-validation`.
|
|
13
|
+
- Fixable defect: `changeledger review <id> fail --retry "<reason>"` →
|
|
14
|
+
`in-progress`.
|
|
15
|
+
- Scope/decision escalation: `changeledger review <id> fail --block "<reason>"`
|
|
16
|
+
→ `blocked` for the human.
|
|
17
|
+
|
|
18
|
+
After a retry, the correction stays uncommitted until another clean reviewer
|
|
19
|
+
passes it. Then commit correction + ledger before asking for human validation.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Authoring a Change
|
|
2
|
+
|
|
3
|
+
## Repository layout
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
.changeledger/
|
|
7
|
+
config.yml
|
|
8
|
+
changes/<id>-<english-slug>.md
|
|
9
|
+
specs/
|
|
10
|
+
AGENTS.md
|
|
11
|
+
CLAUDE.md # optional
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The project-owned `AGENTS.md` contains the ChangeLedger bootstrap. Run
|
|
15
|
+
`changeledger context` before acting; no per-machine contract link is required.
|
|
16
|
+
|
|
17
|
+
## Change document
|
|
18
|
+
|
|
19
|
+
A change is one Markdown file with YAML frontmatter and fixed English stage
|
|
20
|
+
headings. Required frontmatter:
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
---
|
|
24
|
+
id: "20260613-134548"
|
|
25
|
+
title: Short, clear title
|
|
26
|
+
type: feature
|
|
27
|
+
status: draft
|
|
28
|
+
created: 2026-06-13T13:45:48Z
|
|
29
|
+
depends_on: []
|
|
30
|
+
owner: ana # optional
|
|
31
|
+
release_impact: minor # optional: none | patch | minor | major
|
|
32
|
+
---
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`owner` is assigned on `approved → in-progress` when absent, preferring the
|
|
36
|
+
GitHub login and falling back to `git config user.name`.
|
|
37
|
+
|
|
38
|
+
Stages use this order:
|
|
39
|
+
|
|
40
|
+
| Key | Heading | Purpose |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| request | `## Request` | Ask, context and why |
|
|
43
|
+
| investigation | `## Investigation` | Current state, evidence, constraints, risks |
|
|
44
|
+
| proposal | `## Proposal` | Chosen solution and discarded alternatives |
|
|
45
|
+
| specification | `## Specification` | Testable acceptance criteria |
|
|
46
|
+
| plan | `## Plan` | Actionable checklist |
|
|
47
|
+
| log | `## Log` | Chronological execution decisions |
|
|
48
|
+
|
|
49
|
+
Use only the stages activated for the type in `config.yml`. Defaults are:
|
|
50
|
+
|
|
51
|
+
| Type | request | investigation | proposal | specification | plan | log |
|
|
52
|
+
|---|:---:|:---:|:---:|:---:|:---:|:---:|
|
|
53
|
+
| feature | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
54
|
+
| bug | ✓ | ✓ | — | ✓ | ✓ | ✓ |
|
|
55
|
+
| audit | ✓ | ✓ | — | — | — | ✓ |
|
|
56
|
+
| refactor | ✓ | — | ✓ | — | ✓ | ✓ |
|
|
57
|
+
| chore | ✓ | — | — | — | ✓ | — |
|
|
58
|
+
|
|
59
|
+
## Acceptance criteria
|
|
60
|
+
|
|
61
|
+
Each criterion is a separate `### CRn — name` block:
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
### CR1 — Short name
|
|
65
|
+
- **Given** concrete precondition
|
|
66
|
+
- **When** concrete action
|
|
67
|
+
- **Then** exact result
|
|
68
|
+
- **And** optional additional result
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The heading, ids and Given/When/Then/And keywords are fixed English. Localized
|
|
72
|
+
headings, inline criteria and `#### CR1` are not machine-readable.
|
|
73
|
+
|
|
74
|
+
## Plan tasks
|
|
75
|
+
|
|
76
|
+
```markdown
|
|
77
|
+
- [ ] Update `src/foo.mjs`; verify: `node --test test/foo.test.mjs` (CR1)
|
|
78
|
+
- [x] Update `src/foo.mjs`; verify: `node --test test/foo.test.mjs` (CR1) — 2026-06-13T14:20:00Z
|
|
79
|
+
- [!] Update `src/foo.mjs`; verify: `node --test test/foo.test.mjs` (CR1) — reason
|
|
80
|
+
- [ ] Operational step with no observable behavior (support)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The final `(CRn)` block provides traceability. Put target and verification text
|
|
84
|
+
before it; the trailing em-dash suffix is reserved for done timestamps or block
|
|
85
|
+
reasons. `(support)` is only for truly operational work.
|
|
86
|
+
|
|
87
|
+
## IDs and language
|
|
88
|
+
|
|
89
|
+
The id is the UTC creation instant in `YYYYMMDD-HHMMSS` form. Filename is
|
|
90
|
+
`{id}-{english-slug}.md`; the slug is always English and kebab ASCII.
|
|
91
|
+
|
|
92
|
+
Frontmatter keys/enums, stage headings, criterion keywords, markers, filenames
|
|
93
|
+
and CLI stay English. Titles, prose and task descriptions follow the configured
|
|
94
|
+
language.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Human Validation — Stop
|
|
2
|
+
|
|
3
|
+
Implementation and required review are complete. Do not modify the result or
|
|
4
|
+
mark it done. Ask the human to test the whole change in the viewer.
|
|
5
|
+
|
|
6
|
+
Acceptance reaches `done`. Rejection requires a reason and returns the same
|
|
7
|
+
change to `in-progress`; update Specification/Plan as needed and repeat review
|
|
8
|
+
when configured. The agent never accepts on the human's behalf. `done` and
|
|
9
|
+
`discarded` never reopen.
|