@sylad/cadence 1.38.1 → 1.40.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/docs/perf.md CHANGED
@@ -71,6 +71,8 @@ perf:
71
71
  An unknown key (under `perf`, under a model, or a model other than `sonnet`, `opus`, `haiku`), a negative or non-numeric price, or an unreadable file refuses the command before any journal is read (`raf: …`, exit 1, no output).
72
72
  Without `perf.prices` (absent or empty) the cost is `n/d` and a warning says where to declare it; the other indicators are served.
73
73
 
74
+ The same grid prices the waves (L529, [orchestrate](orchestrate.md#cost-in-euros-before-and-after-a-wave-l529)): `orchestrate --dry-run` announces an estimate in euros per lot and for the wave, the final table and `--status` print the real cost.
75
+
74
76
  **Cost of a step** = (`input` + `cacheWrite`) × input price + `output` × output price + `cacheRead` × cacheRead price, per million tokens, at the price of the step's own model. Assumptions written in the sheet (`docs/specs/perf-tokens-delais-cout/fiche.yaml`, R8):
75
77
  cache writes are billed at the input price (the grid has no write price, so the cost is slightly underestimated if they are billed more); a step that only carries `counted` (an old journal) is split 90 % input, 10 % output, no cache read;
76
78
  a step without any readable token costs 0 € (the lot stays in the population); a `local` step costs 0 € whatever its counters (outside quota and budget) and needs no price.
package/docs/releasing.md CHANGED
@@ -86,6 +86,10 @@ It refuses, with exit code 2 and nothing written:
86
86
 
87
87
  Write the two forms of the new version in `docs/whats-new.md` **before** running the command: the file may be modified (it is the one tracked file allowed to be, since the version commit holds it) and the command then reads the forms it finds. Run after the forms are written, it exits 0; if it exits 1 the version files are already written, so fix `docs/whats-new.md` by hand and do not run the command again (it would bump once more).
88
88
 
89
+ The check reads the whole « In two lines » list, as `test/readme-accueil.test.ts` (R5) does at the gate, and not only the line of the new version (L418): a bullet of any other version over 240 characters, or a long paragraph (`**x.y.z**: …`, no leading `- `) that fell among the short lines, is a finding too (exit 1). That is the 1.22.0 publication of 28-10, stopped by that very test after a long form had been committed in the list; the command now says it before the version commit and the tag.
90
+
91
+ The steps it prints are read by their exit code, never through a pipe: a `| tail` or a trailing `| grep` after the suite hands the shell the filter's code, and a red suite looks green (28-10, 29-10). The same holds for the workflows: `publish.yml` and `tests.yml` read the output of `npm publish` (and the diagnostics) with `grep … <<< "$out"`, no pipe (`test/publish-workflow.test.ts`), because under `set -o pipefail` a `printf | grep -q` over the long output of the suite would fail on a `SIGPIPE`.
92
+
89
93
  `docs/whats-new.md` is **not written by the command** (the two forms are prose, written by hand or by a session): it checks that
90
94
  both are there and in their place, and says where to write what is missing. The « In two lines » line of the version is the
91
95
  first of the list and at most 240 characters; the long paragraph is the first of « Version by version », right after its
package/docs/session.md CHANGED
@@ -123,3 +123,35 @@ The command deletes nothing, never fails on the cleanup and does not change the
123
123
  The commands get `CADENCE_SINCE` and `CADENCE_TODAY`. `CADENCE_SINCE` is the `--since` as given; on `session close` without `--since` it is the instant of the last `session start` as an ISO 8601 UTC string (`2026-09-28T07:12:00.000Z`), or `<today> 00:00` when no mark exists.
124
124
  The commands add facts and decide nothing: a failing command is reported and changes neither
125
125
  the exit code nor the verdict.
126
+
127
+ ## Memory index size (L442)
128
+
129
+ Claude Code loads the `MEMORY.md` index of the folder it was launched in at every turn: a long index is a
130
+ fixed cost of every session. `cadence session close` weighs it and, above a threshold, prints a "Mémoire"
131
+ section:
132
+
133
+ ```
134
+ Mémoire : l'index MEMORY.md pèse 15700 octets (seuil 12000)
135
+ 14 entrée(s) datée(s) (9100 octets) à regrouper sous une ligne vers un index secondaire — le skill propose, l'humain décide
136
+ ```
137
+
138
+ - **Where it looks.** `<CLAUDE_CONFIG_DIR or ~/.claude>/projects/<folder>/memory/MEMORY.md`, where `<folder>` is the
139
+ working directory of the command (never the git root: Claude Code indexes the folder it was launched in) with every
140
+ character that is not a letter or a digit replaced by `-`. A symbolic link is followed. With `--all`, each project
141
+ section weighs its own memory.
142
+ - **When it speaks.** Only when the file is strictly larger than the threshold, in bytes: 12000 by default, or
143
+ `memory.indexMaxBytes` (an integer ≥ 1) in the `cadence.yaml` the command reads. An absent index, an empty one or
144
+ one at the threshold prints nothing. A value that is not an integer ≥ 1 stops the close (exit code 2, no report), as
145
+ `session.cleanDays` does.
146
+ - **Dated entries.** A list line (`- `) whose text starts with a day `dd-mm`, after at most `**`, `[` and `⚠`
147
+ (`- **[31-10 : …`). The name of the linked file does not count, so the line that points to the secondary index is
148
+ never counted. With none, the section says `aucune entrée datée à regrouper`.
149
+ - **What it does not do.** It is a proposal, not a condition: the exit code and the « prêt à fermer » line are those of
150
+ a close without the warning, and cadence never writes the memory. The [session-close skill](skills.md) proposes the
151
+ grouping and moves the entries only after the human agrees.
152
+ - **Unreadable index** (a folder, no read permission): one line `Mémoire : l'index MEMORY.md est illisible (<cause>), sa taille n'est pas contrôlée`; the rest of the report is printed.
153
+
154
+ ```yaml
155
+ memory:
156
+ indexMaxBytes: 12000 # bytes; the default
157
+ ```
package/docs/whats-new.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  ## In two lines
6
6
 
7
+ - **1.40.0**: `docs/concepts.md`, the notions of cadence for a human; a proposed sub-task maybe already done is flagged; a warning when the memory index loaded every turn grows too big.
8
+ - **1.39.0**: `orchestrate --continue` fills free slots by priority, one worktree per lot when the cap allows (issue #21); waves show their cost in euros before and after.
7
9
  - **1.38.1**: `spec green` seals a lot closed at `vert: true` without fingerprints (issue #20); `deliver`, `raf move`, `spec reseal` and `spec green` refuse cleanly during a local task.
8
10
  - **1.38.0**: an express lane plays a touch-up of at most 0.1 day in one session; `raf add --local` and `cadence local start|done|abort` lock a repository while the lead edits it by hand.
9
11
  - **1.37.0**: one full test suite per lot, played by the gate (`suites` column); no correction pass without a finding; a richer implementation brief; `scripts/temps-d-un-lot.mjs` measures where a lot's time goes.
@@ -67,6 +69,10 @@ Each is a paragraph in [docs/whats-new.md](whats-new.md) and a full section in [
67
69
 
68
70
  The long form of « In two lines » above (the README no longer carries a « What's new » section since L326: it links here). The full history, with the date of each version, is in [CHANGELOG.md](../CHANGELOG.md).
69
71
 
72
+ **1.40.0**: a guide for humans, `docs/concepts.md`, linked at the top of the README, explains each notion of cadence in a few sentences, in the order you meet them: plan and lot, verdicts, session and wave, the steps of a lot and who plays each, the test gate, worktree and integration, « livrable jusqu'à » (L460). In the final table and `--status --detail`, a proposed sub-task whose cited file was changed by a commit of the lot after the review that proposed it is marked `— peut-être déjà traitée (<sha>)`, so a review no longer feeds the next one with work already done (L422). `cadence session close` and `cadence lead tour` warn when the Claude Code `MEMORY.md` index, loaded at every turn, outgrows a size threshold (`memory.indexMaxBytes`), and propose to group its dated entries behind one line; `cadence config set` reads that key back like the others, so a wrong value stops with nothing written (L442). A measure of the earlier change to the passes, read on two windows of `cadence perf`, is recorded (L430).
73
+
74
+ **1.39.0**: free slots no longer stay empty (GitHub issue #21, L527, `docs/orchestrate.md`). With `--continue`, once the order is agreed (`--priority` or `priority:` of the parent `cadence.yaml`), the wave starts the next ready lot in each slot as soon as one frees up — a lot handed back at its pre-check frees its slot in seconds —, in priority order, within the session cap, the shared resources and one session per repository or one worktree per lot, and the journal says so. In a repository with `orchestrate.worktrees: true` and a cap above 1, every lot gets its own worktree, a lot launched alone or brought by `--add` included, so a second lot of the same repository plays in parallel instead of waiting; `--dry-run --continue` now simulates the draws one by one, as the wave plays them. `cadence orchestrate --dry-run` also announces the cost in euros of each lot and of the wave beside its token budget, and the final table and `--status` show the real cost (L529, price grid `perf.prices`). `cadence release` reads the « In two lines » section of `docs/whats-new.md` the way the test does, so a line too long or a duplicate is caught before the tag (L418), and a timing test that turned red under load in a fresh clone has a wide margin (L528).
75
+
70
76
  **1.38.1**: `cadence spec green <lot>` now handles a lot closed at `vert: true` with no fingerprints (closed before the seal, GitHub issue #20): it replays the lot's acceptance command and, green, writes the fingerprints in a commit that cites the lot, so a later lot that amends one of its tests no longer has to be finished outside a wave (L526, `docs/orchestrate.md`). During a local task of the lead (1.38.0), `cadence deliver`, `raf move`, `cadence spec reseal` and `cadence spec green` refuse with a message that names the task and how to end it, instead of « état illisible » or an impossible `--sha` hint (L525, `docs/raf.md`).
71
77
 
72
78
  **1.38.0**: two ways to make a small change cheaper (L519, decided on 01-11 after a one-line UI separator cost 245 s of implementation). The **express lane**: a lot of at most 0.1 day with no screen sheet nor spec is played by `cadence orchestrate` in a single writing session, without precheck, edge-case probe, separate code review or « code sans test » gate, and without a News entry per lot; the lead reads the diff and the capture, groups the entries at delivery, and the program's gate still plays once (`docs/orchestrate.md`). The **local task**: `raf add --local` marks a lot the lead does by hand, and `cadence local start <lot>` locks the repository like a wave (no wave starts there, `--add` and `--continue` refuse it, and the task itself is refused while a wave or another lot of the repository runs). The lock is declared with a `--ttl` (60 min by default, like `lead hold`) and carried by no process; past its TTL it still holds and `lead tour` and `orchestrate --status` show a ⚠ until `cadence local done` (gate green) or `cadence local abort`. A wave refuses a `local` lot, and the pre-push hook recognises the task instead of reporting an unreadable wave (`docs/raf.md`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sylad/cadence",
3
- "version": "1.38.1",
3
+ "version": "1.40.0",
4
4
  "description": "A small, repo-native working method: a versioned plan linked to your commits, a changelog with screenshots, session rituals and deliveries proven by their effect.",
5
5
  "license": "MIT",
6
6
  "author": "Sylvain Ladoire",
@@ -37,6 +37,15 @@
37
37
  "docs/qualite.md",
38
38
  "docs/overview.md",
39
39
  "docs/whats-new.md",
40
+ "docs/concepts.md",
41
+ "docs/concepts-lot-light.svg",
42
+ "docs/concepts-lot-dark.svg",
43
+ "docs/concepts-vague-light.svg",
44
+ "docs/concepts-vague-dark.svg",
45
+ "docs/concepts-worktrees-light.svg",
46
+ "docs/concepts-worktrees-dark.svg",
47
+ "docs/concepts-livraison-light.svg",
48
+ "docs/concepts-livraison-dark.svg",
40
49
  "docs/fonctionnement.md",
41
50
  "docs/fonctionnement-lot-light.svg",
42
51
  "docs/fonctionnement-lot-dark.svg",
@@ -64,6 +64,12 @@ not truncated) or on a net bottleneck (`⚠ goulot`): at most one improvement lo
64
64
  their place, and the human decides. Never open a lot for a micro-optimisation or for the variation of a single window.
65
65
  Without a `⚠`, the header is empty and you say nothing about perf.
66
66
 
67
+ A line `mémoire · MEMORY.md <n> octets > seuil <s> · …` (after the worktree lines) says the `MEMORY.md` index of the parent
68
+ folder, loaded at every turn of your session, weighs more than `memory.indexMaxBytes` (12000 bytes by default): relay it in one
69
+ line and propose to group its dated entries under one line that points to a secondary index. Do it only after the human agrees;
70
+ the tour only measures, it never writes the memory. A line `mémoire · MEMORY.md illisible (…)` or the error line
71
+ `cadence.yaml · ✗ erreur : memory.indexMaxBytes …` is relayed as it is. `--json` never carries it.
72
+
67
73
  Then report to the human in a compact table — one row per project — and propose **three** items
68
74
  across projects, each with project, lot id and one sentence of justification: finish what is in
69
75
  progress, then drift that blocks a delivery, then ready quick wins. **Stop and wait for the priority.**
@@ -59,6 +59,12 @@ With no project named, run `cadence session close --all` from the parent folder,
59
59
  4. **Memory, filtered** (only if you keep a persistent memory): write down what the repository does
60
60
  NOT already say — a trap and its cause, a decision or correction from the human, a collaboration
61
61
  rule. Test: "do `git log` or the docs already say it?" → then no memory.
62
+ When the report has a section "Mémoire" (the `MEMORY.md` index of this folder weighs more than
63
+ `memory.indexMaxBytes` of `cadence.yaml`, 12000 bytes by default), propose to group the dated entries it
64
+ counts under one line that points to a secondary index (a memory file holding them): the index is loaded
65
+ at every turn, so its weight is paid by every session. Move the entries only after the human agrees, then
66
+ run `cadence session close` again — the section is gone or the size has dropped. Without the agreement
67
+ nothing moves and the warning comes back at the next close. The command never writes the memory.
62
68
  5. **Skills and agents, on threshold, PROPOSED**: a skill when the same chain of commands was done by
63
69
  hand at least twice today; an agent update when an agent got something wrong or its domain moved.
64
70
  List them with the benefit; the human decides. Never create them here.