@sylad/cadence 1.6.0 → 1.7.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +45 -1734
- package/agents/acceptance-writer.md +1 -0
- package/dist/audit.js +4 -3
- package/dist/cli.js +4 -4
- package/dist/orchestrate/accept.js +8 -3
- package/dist/orchestrate/briefs.js +1 -1
- package/dist/orchestrate/command.js +3 -0
- package/dist/orchestrate/cycle.js +68 -6
- package/docs/cadence-hud.md +50 -0
- package/docs/corrections.md +24 -0
- package/docs/cycle-vague-dark.svg +42 -0
- package/docs/cycle-vague-light.svg +42 -0
- package/docs/deliver.md +204 -0
- package/docs/fonctionnement-lead-dark.svg +101 -0
- package/docs/fonctionnement-lead-light.svg +101 -0
- package/docs/fonctionnement-lot-dark.svg +38 -0
- package/docs/fonctionnement-lot-light.svg +38 -0
- package/docs/fonctionnement-service-dark.svg +23 -0
- package/docs/fonctionnement-service-light.svg +23 -0
- package/docs/fonctionnement-wave-dark.svg +66 -0
- package/docs/fonctionnement-wave-light.svg +66 -0
- package/docs/fonctionnement.md +106 -0
- package/docs/lead-workflow-dark.svg +200 -0
- package/docs/lead-workflow-light.svg +200 -0
- package/docs/lead.md +147 -0
- package/docs/news.md +245 -0
- package/docs/orchestrate.md +639 -0
- package/docs/overview.md +27 -0
- package/docs/raf.md +192 -0
- package/docs/releasing.md +59 -0
- package/docs/session.md +107 -0
- package/docs/skills.md +76 -0
- package/docs/spec.md +60 -0
- package/docs/stabilite.md +35 -0
- package/docs/whats-new.md +81 -0
- package/package.json +28 -1
- package/templates/acceptation-runner.mjs +1 -1
- package/templates/fiche-back.yaml +1 -1
- package/templates/fiche.yaml +1 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1650 810" width="1650" height="810" role="img" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif" font-size="13" fill="#1f2328">
|
|
2
|
+
<title>Workflow of the lead skill in three lanes: the human, the lead session, and the orchestrate program with its agents</title>
|
|
3
|
+
<defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#57606a"/></marker>
|
|
4
|
+
<marker id="arrw" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#cf222e"/></marker></defs>
|
|
5
|
+
<rect width="1650" height="810" fill="#ffffff"/>
|
|
6
|
+
<text x="825" y="34" text-anchor="middle" font-size="18" font-weight="600">The lead workflow: decide at the top, work in fresh sessions</text>
|
|
7
|
+
<rect x="10" y="70" width="1630" height="200" fill="#f6f8fa" stroke="#d0d7de"/>
|
|
8
|
+
<line x1="150" y1="70" x2="150" y2="270" stroke="#d0d7de"/>
|
|
9
|
+
<text x="24" y="146" font-weight="700" font-size="15" fill="#bf8700">Human</text>
|
|
10
|
+
<text x="24" y="166" font-size="11.5" fill="#57606a">chooses, answers,</text>
|
|
11
|
+
<text x="24" y="181" font-size="11.5" fill="#57606a">gives the UX verdict</text>
|
|
12
|
+
<rect x="10" y="270" width="1630" height="200" fill="#ffffff" stroke="#d0d7de"/>
|
|
13
|
+
<line x1="150" y1="270" x2="150" y2="470" stroke="#d0d7de"/>
|
|
14
|
+
<text x="24" y="339" font-weight="700" font-size="15" fill="#0969da">Lead session</text>
|
|
15
|
+
<text x="24" y="359" font-size="11.5" fill="#57606a">stays small:</text>
|
|
16
|
+
<text x="24" y="374" font-size="11.5" fill="#57606a">reads, decides, checks,</text>
|
|
17
|
+
<text x="24" y="389" font-size="11.5" fill="#57606a">delivers</text>
|
|
18
|
+
<rect x="10" y="470" width="1630" height="320" fill="#f6f8fa" stroke="#d0d7de"/>
|
|
19
|
+
<line x1="150" y1="470" x2="150" y2="790" stroke="#d0d7de"/>
|
|
20
|
+
<text x="24" y="606" font-weight="700" font-size="15" fill="#1a7f37">orchestrate</text>
|
|
21
|
+
<text x="24" y="626" font-size="11.5" fill="#57606a">program and agents</text>
|
|
22
|
+
<text x="24" y="641" font-size="11.5" fill="#57606a">(fresh short sessions)</text>
|
|
23
|
+
<text x="240" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">1 Tour</text>
|
|
24
|
+
<text x="420" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">2 Wave</text>
|
|
25
|
+
<text x="600" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">3 Relay</text>
|
|
26
|
+
<text x="780" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">4 Review</text>
|
|
27
|
+
<text x="960" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">5 Re-check</text>
|
|
28
|
+
<text x="1140" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">6 Delivery</text>
|
|
29
|
+
<text x="1320" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">7 Threshold</text>
|
|
30
|
+
<text x="1500" y="88" text-anchor="middle" font-size="11.5" font-weight="600" fill="#57606a">8 Close</text>
|
|
31
|
+
<g id="tour"><rect x="161" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
32
|
+
<text x="240" y="358.5" text-anchor="middle" font-weight="600" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">cadence lead tour</text>
|
|
33
|
+
<text x="240" y="374.5" text-anchor="middle">one line per project</text>
|
|
34
|
+
<text x="240" y="390.5" text-anchor="middle">+ three proposals</text>
|
|
35
|
+
</g>
|
|
36
|
+
<g id="choose"><rect x="161" y="137" width="158" height="66" rx="8" fill="#fff8c5" stroke="#bf8700" stroke-width="1.5"/>
|
|
37
|
+
<text x="240" y="158.5" text-anchor="middle" font-weight="600">Picks the lots</text>
|
|
38
|
+
<text x="240" y="174.5" text-anchor="middle">and the order</text>
|
|
39
|
+
<text x="240" y="190.5" text-anchor="middle">(the priority)</text>
|
|
40
|
+
</g>
|
|
41
|
+
<g id="launch"><rect x="341" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
42
|
+
<text x="420" y="358.5" text-anchor="middle" font-weight="600">Starts the wave</text>
|
|
43
|
+
<text x="420" y="374.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">orchestrate … --wave</text>
|
|
44
|
+
<text x="420" y="390.5" text-anchor="middle">in the background</text>
|
|
45
|
+
</g>
|
|
46
|
+
<g id="precheck"><rect x="161" y="508" width="158" height="82" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
47
|
+
<text x="240" y="529.5" text-anchor="middle" font-weight="600">Precheck</text>
|
|
48
|
+
<text x="240" y="545.5" text-anchor="middle">local model or Sonnet:</text>
|
|
49
|
+
<text x="240" y="561.5" text-anchor="middle">already delivered?</text>
|
|
50
|
+
<text x="240" y="577.5" text-anchor="middle">yes → back to lead</text>
|
|
51
|
+
</g>
|
|
52
|
+
<g id="spec"><rect x="341" y="480" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
53
|
+
<text x="420" y="501.5" text-anchor="middle" font-weight="600">Spec (screen: page)</text>
|
|
54
|
+
<text x="420" y="517.5" text-anchor="middle">spec-writer: mockup</text>
|
|
55
|
+
<text x="420" y="533.5" text-anchor="middle">+ sheet, 1440 / 390</text>
|
|
56
|
+
</g>
|
|
57
|
+
<g id="mockup"><rect x="521" y="480" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
58
|
+
<text x="600" y="501.5" text-anchor="middle" font-weight="600">Mockup review</text>
|
|
59
|
+
<text x="600" y="517.5" text-anchor="middle">ux-reviewer, 2 passes</text>
|
|
60
|
+
<text x="600" y="533.5" text-anchor="middle">max, then handed back</text>
|
|
61
|
+
</g>
|
|
62
|
+
<g id="backspec"><rect x="341" y="552" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
63
|
+
<text x="420" y="573.5" text-anchor="middle" font-weight="600">Back-end spec</text>
|
|
64
|
+
<text x="420" y="589.5" text-anchor="middle">spec: true: cases,</text>
|
|
65
|
+
<text x="420" y="605.5" text-anchor="middle">rules, contracts</text>
|
|
66
|
+
</g>
|
|
67
|
+
<g id="sheetreview"><rect x="521" y="552" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
68
|
+
<text x="600" y="573.5" text-anchor="middle" font-weight="600">Sheet review</text>
|
|
69
|
+
<text x="600" y="589.5" text-anchor="middle">code-reviewer, 2</text>
|
|
70
|
+
<text x="600" y="605.5" text-anchor="middle">passes max</text>
|
|
71
|
+
</g>
|
|
72
|
+
<g id="accept"><rect x="701" y="480" width="158" height="138" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
73
|
+
<text x="780" y="543" text-anchor="middle" font-weight="600">Accept</text>
|
|
74
|
+
<text x="780" y="559" text-anchor="middle">red tests + lock</text>
|
|
75
|
+
<text x="780" y="575" text-anchor="middle">if accept declared</text>
|
|
76
|
+
</g>
|
|
77
|
+
<g id="implement"><rect x="341" y="650" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5"/>
|
|
78
|
+
<text x="420" y="671.5" text-anchor="middle" font-weight="600">Implementation</text>
|
|
79
|
+
<text x="420" y="687.5" text-anchor="middle">test first, commits</text>
|
|
80
|
+
<text x="420" y="703.5" text-anchor="middle">cite the lot</text>
|
|
81
|
+
</g>
|
|
82
|
+
<g id="relay"><rect x="521" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
83
|
+
<text x="600" y="358.5" text-anchor="middle" font-weight="600">Relays the journal</text>
|
|
84
|
+
<text x="600" y="374.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">tail -F journal.log</text>
|
|
85
|
+
<text x="600" y="390.5" text-anchor="middle">one sentence per line</text>
|
|
86
|
+
</g>
|
|
87
|
+
<g id="answer"><rect x="521" y="137" width="158" height="66" rx="8" fill="#fff8c5" stroke="#bf8700" stroke-width="1.5"/>
|
|
88
|
+
<text x="600" y="158.5" text-anchor="middle" font-weight="600">Answers a question</text>
|
|
89
|
+
<text x="600" y="174.5" text-anchor="middle">the lead never</text>
|
|
90
|
+
<text x="600" y="190.5" text-anchor="middle">answers for them</text>
|
|
91
|
+
</g>
|
|
92
|
+
<g id="uxpass"><rect x="521" y="650" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
93
|
+
<text x="600" y="671.5" text-anchor="middle" font-weight="600">UX pass</text>
|
|
94
|
+
<text x="600" y="687.5" text-anchor="middle">visible lot + app</text>
|
|
95
|
+
<text x="600" y="703.5" text-anchor="middle">declared; vs mockup</text>
|
|
96
|
+
</g>
|
|
97
|
+
<g id="codereview"><rect x="701" y="650" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5"/>
|
|
98
|
+
<text x="780" y="671.5" text-anchor="middle" font-weight="600">Code review</text>
|
|
99
|
+
<text x="780" y="687.5" text-anchor="middle">Opus (Sonnet ≤ 0.25 d)</text>
|
|
100
|
+
<text x="780" y="703.5" text-anchor="middle">records raf review</text>
|
|
101
|
+
</g>
|
|
102
|
+
<g id="fix"><rect x="881" y="650" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
103
|
+
<text x="960" y="671.5" text-anchor="middle" font-weight="600">Correction</text>
|
|
104
|
+
<text x="960" y="687.5" text-anchor="middle">new session, 2 passes</text>
|
|
105
|
+
<text x="960" y="703.5" text-anchor="middle">3rd if it converges</text>
|
|
106
|
+
</g>
|
|
107
|
+
<g id="table"><rect x="701" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
108
|
+
<text x="780" y="358.5" text-anchor="middle" font-weight="600">Final table</text>
|
|
109
|
+
<text x="780" y="374.5" text-anchor="middle">ready · handed back</text>
|
|
110
|
+
<text x="780" y="390.5" text-anchor="middle">· « livrable jusqu'à »</text>
|
|
111
|
+
</g>
|
|
112
|
+
<g id="recheck"><rect x="881" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
113
|
+
<text x="960" y="358.5" text-anchor="middle" font-weight="600">Re-verifies itself</text>
|
|
114
|
+
<text x="960" y="374.5" text-anchor="middle">git log · tests · build</text>
|
|
115
|
+
<text x="960" y="390.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">raf check</text>
|
|
116
|
+
</g>
|
|
117
|
+
<g id="uxverdict"><rect x="881" y="137" width="158" height="66" rx="8" fill="#fff8c5" stroke="#bf8700" stroke-width="1.5"/>
|
|
118
|
+
<text x="960" y="158.5" text-anchor="middle" font-weight="600">Looks at the captures</text>
|
|
119
|
+
<text x="960" y="174.5" text-anchor="middle">UX verdict →</text>
|
|
120
|
+
<text x="960" y="190.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">raf ux (visible lot)</text>
|
|
121
|
+
</g>
|
|
122
|
+
<g id="done"><rect x="1061" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
123
|
+
<text x="1140" y="358.5" text-anchor="middle" font-weight="600" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">raf done</text>
|
|
124
|
+
<text x="1140" y="374.5" text-anchor="middle">then push</text>
|
|
125
|
+
<text x="1140" y="390.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">cadence deliver</text>
|
|
126
|
+
</g>
|
|
127
|
+
<g id="qa"><rect x="1061" y="650" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5" stroke-dasharray="5 3"/>
|
|
128
|
+
<text x="1140" y="671.5" text-anchor="middle" font-weight="600">qa-reviewer</text>
|
|
129
|
+
<text x="1140" y="687.5" text-anchor="middle">reads only; blocking</text>
|
|
130
|
+
<text x="1140" y="703.5" text-anchor="middle">findings → the human</text>
|
|
131
|
+
</g>
|
|
132
|
+
<g id="ctx"><rect x="1241" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
133
|
+
<text x="1320" y="358.5" text-anchor="middle" font-weight="600">Context under 60 %?</text>
|
|
134
|
+
<text x="1320" y="374.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">session context</text>
|
|
135
|
+
<text x="1320" y="390.5" text-anchor="middle">error = at threshold</text>
|
|
136
|
+
</g>
|
|
137
|
+
<g id="next"><rect x="1241" y="650" width="158" height="66" rx="8" fill="#dafbe1" stroke="#1a7f37" stroke-width="1.5"/>
|
|
138
|
+
<text x="1320" y="671.5" text-anchor="middle" font-weight="600">Next wave</text>
|
|
139
|
+
<text x="1320" y="687.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">… --continue</text>
|
|
140
|
+
<text x="1320" y="703.5" text-anchor="middle">draws the next ready lot</text>
|
|
141
|
+
</g>
|
|
142
|
+
<g id="close"><rect x="1421" y="337" width="158" height="66" rx="8" fill="#ddf4ff" stroke="#0969da" stroke-width="1.5"/>
|
|
143
|
+
<text x="1500" y="358.5" text-anchor="middle" font-weight="600">Close</text>
|
|
144
|
+
<text x="1500" y="374.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">session-close</text>
|
|
145
|
+
<text x="1500" y="390.5" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11.5">session next ×3</text>
|
|
146
|
+
</g>
|
|
147
|
+
<g id="report"><rect x="1421" y="137" width="158" height="66" rx="8" fill="#fff8c5" stroke="#bf8700" stroke-width="1.5"/>
|
|
148
|
+
<text x="1500" y="158.5" text-anchor="middle" font-weight="600">One line per project</text>
|
|
149
|
+
<text x="1500" y="174.5" text-anchor="middle">delivered · in progress</text>
|
|
150
|
+
<text x="1500" y="190.5" text-anchor="middle">· blocked (and why)</text>
|
|
151
|
+
</g>
|
|
152
|
+
<polyline points="240,337 240,203" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
153
|
+
<text x="248" y="236" text-anchor="start" font-size="11" fill="#57606a" class="lbl">proposals</text>
|
|
154
|
+
<polyline points="319,170 420,170 420,337" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
155
|
+
<text x="414" y="164" text-anchor="end" font-size="11" fill="#57606a" class="lbl">choice</text>
|
|
156
|
+
<polyline points="499,683 521,683" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
157
|
+
<polyline points="679,683 701,683" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
158
|
+
<polyline points="859,683 881,683" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
159
|
+
<polyline points="960,650 960,632 820,632 820,650" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
160
|
+
<text x="968" y="626" text-anchor="start" font-size="11" fill="#57606a" class="lbl">then review again</text>
|
|
161
|
+
<polyline points="870,683 870,430 780,430 780,403" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
162
|
+
<text x="876" y="446" text-anchor="start" font-size="11" fill="#57606a" class="lbl">wave ends</text>
|
|
163
|
+
<polyline points="510,683 510,430 600,430 600,403" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
164
|
+
<text x="516" y="646" text-anchor="start" font-size="11" fill="#57606a" class="lbl">journal</text>
|
|
165
|
+
<polyline points="630,337 630,203" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
166
|
+
<text x="636" y="236" text-anchor="start" font-size="11" fill="#57606a" class="lbl">question</text>
|
|
167
|
+
<polyline points="570,203 570,337" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
168
|
+
<text x="564" y="236" text-anchor="end" font-size="11" class="lbl" fill="#57606a">--resume --answer</text>
|
|
169
|
+
<polyline points="859,370 881,370" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
170
|
+
<polyline points="960,203 960,337" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
171
|
+
<text x="968" y="236" text-anchor="start" font-size="11" fill="#57606a" class="lbl">on the human's verdict,</text>
|
|
172
|
+
<text x="968" y="251" text-anchor="start" font-size="11" fill="#57606a" class="lbl">or the lead's (lead.ux: lead)</text>
|
|
173
|
+
<polyline points="1039,370 1061,370" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
174
|
+
<polyline points="1140,403 1140,650" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
175
|
+
<polyline points="1320,403 1320,650" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
176
|
+
<text x="1326" y="440" text-anchor="start" font-size="11" fill="#57606a" class="lbl">yes: chain</text>
|
|
177
|
+
<polyline points="1399,370 1421,370" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
178
|
+
<text x="1410" y="329" text-anchor="middle" font-size="11" fill="#57606a" class="lbl">≥ 60 %: close</text>
|
|
179
|
+
<polyline points="1500,337 1500,203" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
180
|
+
<polyline points="1320,716 1320,746 420,746 420,716" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
181
|
+
<text x="870" y="740" text-anchor="middle" font-size="11" fill="#57606a" class="lbl">next wave: back to step 2, the limits still apply</text>
|
|
182
|
+
<rect x="170" y="760" width="22" height="14" rx="3" fill="none" stroke="#57606a" stroke-dasharray="5 3"/>
|
|
183
|
+
<text x="200" y="771" font-size="11.5" fill="#57606a">conditional step</text>
|
|
184
|
+
<text x="340" y="771" font-size="11.5" fill="#57606a">The lead never commits where a wave runs, and never delivers two projects at once. At most as many sessions or subagents as the cap the human sets (CADENCE_MAX_SESSIONS, 2 by default).</text>
|
|
185
|
+
<polyline points="420,403 420,440 240,440 240,508" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
186
|
+
<polyline points="319,549 330,549 330,513 341,513" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
187
|
+
<polyline points="330,549 330,585 341,585" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
188
|
+
<polyline points="499,513 521,513" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
189
|
+
<polyline points="679,513 701,513" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
190
|
+
<polyline points="499,585 521,585" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
191
|
+
<polyline points="679,585 701,585" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
192
|
+
<polyline points="240,590 240,683 341,683" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
193
|
+
<polyline points="780,618 780,634 420,634 420,650" fill="none" stroke="#57606a" stroke-width="1.6" marker-end="url(#arr)"/>
|
|
194
|
+
<text x="232" y="640" text-anchor="end" font-size="11" fill="#57606a" class="lbl">other lots</text>
|
|
195
|
+
<text x="232" y="655" text-anchor="end" font-size="11" fill="#57606a" class="lbl">go straight on</text>
|
|
196
|
+
<text x="890" y="508" text-anchor="start" font-size="11" fill="#57606a" class="lbl">lots with screen: page</text>
|
|
197
|
+
<text x="890" y="523" text-anchor="start" font-size="11" fill="#57606a" class="lbl">spec, mockup, accept</text>
|
|
198
|
+
<text x="890" y="568" text-anchor="start" font-size="11" fill="#57606a" class="lbl">lots with spec: true</text>
|
|
199
|
+
<text x="890" y="583" text-anchor="start" font-size="11" fill="#57606a" class="lbl">spec, sheet review, accept</text>
|
|
200
|
+
</svg>
|
package/docs/lead.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# The lead workflow
|
|
2
|
+
|
|
3
|
+
The `lead` skill pilots several projects from a parent folder. Its session stays small: it reads
|
|
4
|
+
summaries, decides with the human, and leaves the work to fresh short sessions run by a program
|
|
5
|
+
(`cadence orchestrate`). This page draws who does what, in three lanes: the **human**, the
|
|
6
|
+
**lead session**, and the **`orchestrate` program with its agents**.
|
|
7
|
+
|
|
8
|
+
<picture>
|
|
9
|
+
<source media="(prefers-color-scheme: dark)" srcset="lead-workflow-dark.svg">
|
|
10
|
+
<img alt="The lead workflow in three lanes (human, lead session, orchestrate program and agents), from the tour of the projects to the close of the session" src="lead-workflow-light.svg">
|
|
11
|
+
</picture>
|
|
12
|
+
|
|
13
|
+
Dashed boxes are conditional steps: the precheck runs only for a lot without a commit yet (unless `orchestrate.precheck: false`), and the spec, sheet review and accept steps run only for a `screen: page` lot or a `spec: true` lot. The skill itself is `skills/lead/SKILL.md`; this page is its
|
|
14
|
+
picture, not its source.
|
|
15
|
+
|
|
16
|
+
## The steps
|
|
17
|
+
|
|
18
|
+
1. **Tour.** The lead runs `cadence lead tour` (a program, no model) and reports one row per project.
|
|
19
|
+
It proposes three items: finish what is in progress, then drift that blocks a delivery, then ready
|
|
20
|
+
quick wins. It stops and waits: the human picks the lots and the order (`--priority`, or the
|
|
21
|
+
`priority:` list of the parent folder's `cadence.yaml`).
|
|
22
|
+
2. **Wave.** The lead starts `cadence orchestrate <project>:<lot> … --wave <id>` in the background.
|
|
23
|
+
For each lot the program runs, in fresh sessions and in this order: `precheck → spec → maquette →
|
|
24
|
+
accept → implement → review → ux`. The **precheck** applies to any lot without a commit yet (unless
|
|
25
|
+
`orchestrate.precheck: false`). The spec steps exist only for a lot that declares
|
|
26
|
+
a `screen:` of `page` (a visible lot that creates or changes a whole screen; `screen: component` and `screen: journey`
|
|
27
|
+
lots take the ordinary path, straight to the implementation, unless they already have a sheet) or `spec: true` (a lot without a screen
|
|
28
|
+
that still has a behaviour to pin down: `precheck → spec → fiche → accept → implement → review`);
|
|
29
|
+
spec, sheet review and accept apply to `screen: page` and to `spec: true` alike; the other lots go
|
|
30
|
+
straight from the precheck (when it applies) to the implementation:
|
|
31
|
+
- **spec**: the `spec-writer` agent draws a static mockup to the project's own style and writes the
|
|
32
|
+
screen sheet (`fiche.yaml`: fields, states, numbered rules), rendered at 1440 and 390 px;
|
|
33
|
+
- **fiche** (a lot with a back-end part: `spec: true`, or a screen lot whose sheet has a `sujet` block):
|
|
34
|
+
the `code-reviewer` agent in sheet mode reviews the back-end sheet (two passes at most, then the lot
|
|
35
|
+
is handed back) unless `orchestrate.fiche: false`; a mixed lot has both reviews, and their findings
|
|
36
|
+
go together to a single second `spec` pass. A lot without a screen has no News entry: the
|
|
37
|
+
hypotheses of its final sheet become one note of the lot each, and the end-of-wave table lists them
|
|
38
|
+
as `hypothèse de la fiche : …` — the lead relays them to the human;
|
|
39
|
+
- **maquette**: the `ux-reviewer` agent reviews the mockup (two passes at most, then the lot is handed
|
|
40
|
+
back) unless `orchestrate.maquette: false`;
|
|
41
|
+
- **accept**: a separate session writes the acceptance tests from the sheet, committed red and locked,
|
|
42
|
+
when the project declares `orchestrate.accept`; without it the step is skipped with a warning;
|
|
43
|
+
- the implementation (test first, commits citing the lot) makes them green without touching them;
|
|
44
|
+
- a UX pass if the lot is `visible` and the project says how to see its app (`orchestrate.ux`); for a
|
|
45
|
+
lot with a sheet it is a conformity pass against the mockup;
|
|
46
|
+
- the code review (Opus; Sonnet for a lot of 0.25 day or less), which also follows each rule of the
|
|
47
|
+
sheet to its test;
|
|
48
|
+
- a correction in a new session if the review is not compliant (two passes at most, a third when the review
|
|
49
|
+
converges — blocking + major findings down and only one left —, each followed by a review).
|
|
50
|
+
|
|
51
|
+
The program records `raf review` itself once the review is compliant.
|
|
52
|
+
3. **Relay.** The lead follows the wave's journal (`tail -n +1 -F .cadence/runs/<id>/journal.log`, one
|
|
53
|
+
line per transition) and tells the human each line in one sentence, with no polling loop. A
|
|
54
|
+
question from a session comes back to the human at once; the answer goes in with
|
|
55
|
+
`cadence orchestrate --resume --answer <project>:<lot> "…"`. The lead never answers in the
|
|
56
|
+
human's place. `--drop` and `--stop-after-current` steer a wave that is running.
|
|
57
|
+
4. **Review.** The final table of the wave lists the lots ready, handed back, and the line
|
|
58
|
+
« livrable jusqu'à <sha> » for a ready lot stacked under a handed-back one. Minor findings come back in
|
|
59
|
+
the table: one becomes a lot of its own only if it describes an observable bug.
|
|
60
|
+
5. **Re-check.** The lead verifies itself, one project at a time: `git log`, the test suite and the
|
|
61
|
+
build run by the lead, `raf check` clean. A `visible` lot waits for the human to look at the
|
|
62
|
+
UX reviewer's captures: the lead records `raf ux` on the human's verdict, never on its own — unless the parent folder's `cadence.yaml` says `lead.ux: lead`: then the lead forms the verdict from the reviewer's report and its own look at the captures, and asks the human only at the slightest doubt. Then
|
|
63
|
+
`raf done`.
|
|
64
|
+
6. **Delivery.** Push (for a « livrable jusqu'à <sha> », that sha alone, never HEAD), then
|
|
65
|
+
`cadence deliver`. After a green delivery that changes what a page shows or what it is served, the
|
|
66
|
+
`qa-reviewer` agent walks the delivered pages in a real browser, reads only, and brings its blocking
|
|
67
|
+
findings to the human. It is not a gate: a finding becomes a new lot.
|
|
68
|
+
7. **Threshold and chaining.** Before every new wave the lead reads `cadence session context`. Under
|
|
69
|
+
**60 %** it chains: `cadence orchestrate --continue` draws the next ready lot of the plan, in the
|
|
70
|
+
declared priority, without asking the human « next? ». From 60 % upward, or when the figure cannot
|
|
71
|
+
be read (exit code 2: the band is not loaded, or its figure is stale), it starts nothing. A lot
|
|
72
|
+
that was not handed back ready is reported, not chained over; a question or a UX reservation
|
|
73
|
+
pending on a lot never stops the chain on the other lots.
|
|
74
|
+
8. **Close.** `session-close` in each project touched, filtered memory, three lines for next time
|
|
75
|
+
with `cadence session next` (the wave that was about to start comes first), then one line per project
|
|
76
|
+
to the human: delivered, in progress, blocked (and why).
|
|
77
|
+
|
|
78
|
+
## Permanent rules
|
|
79
|
+
|
|
80
|
+
| Rule | Why |
|
|
81
|
+
|---|---|
|
|
82
|
+
| At most **as many subagents as the session cap** running at once (2 by default; the human sets it with `CADENCE_MAX_SESSIONS`), orchestrate sessions included | `cadence orchestrate --status` and `cadence lead tour` print `créneaux libres : N sur M`, M being the configured cap; the lead never raises `--max-sessions` or `CADENCE_MAX_SESSIONS` itself |
|
|
83
|
+
| Never two sessions in the same repository at the same time; the lead does not commit where a wave runs | a wave's lock refuses `cadence deliver` while a lot still works there |
|
|
84
|
+
| A locked acceptance test that contradicts the sheet is corrected by the lead with `cadence spec reseal <lot> <test> --reason "…"` (lot in progress, outside a wave; an amended sheet is accepted once committed, every commit that touched it citing the lot, L217, never put it back to the red state; a delivered lot with an unstable test: add `--porteur <lot in progress>`, L212), then `--resume --answer` for a lot in question, or a new `cadence orchestrate <project>:<lot>` for a lot handed back (`--resume` skips it) | never by a session, never by editing `acceptation.json` |
|
|
85
|
+
| Deliveries and the `raf ux` / `raf review` verdicts belong to the lead, one project at a time | never to a subagent, never two deliveries in parallel |
|
|
86
|
+
| The UX verdict is the human's unless `lead.ux: lead` (parent `cadence.yaml`, default `human`) | then the lead decides from the report and the captures, and brings any doubt to the human |
|
|
87
|
+
| A session cannot ask the human anything | it stops and reports; the lead brings the question back |
|
|
88
|
+
| Never push or deliver HEAD above a handed-back lot | HEAD holds code that was not reviewed |
|
|
89
|
+
| A plan kept by another tool is read-only for `raf` | its own commands record the lot's state |
|
|
90
|
+
|
|
91
|
+
## Exit codes
|
|
92
|
+
|
|
93
|
+
`cadence orchestrate`:
|
|
94
|
+
|
|
95
|
+
| Code | Meaning |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `0` | every lot is ready |
|
|
98
|
+
| `1` | some lots were handed back to the lead |
|
|
99
|
+
| `2` | refused before acting (a precondition failed) |
|
|
100
|
+
| `3` | wave suspended (budget or usage limit); `--resume --budget …` continues |
|
|
101
|
+
|
|
102
|
+
`cadence session context` exits `2` when it cannot prove the figure (no band, several sessions in
|
|
103
|
+
the folder without `$CLAUDE_CODE_SESSION_ID`, figure older than two minutes): the lead then treats it
|
|
104
|
+
as being at the threshold.
|
|
105
|
+
|
|
106
|
+
The mechanics around it (the life of a lot in the plan, a lot inside a wave, putting cadence in service, the budgets) are drawn in
|
|
107
|
+
[fonctionnement.md](fonctionnement.md). See also the [lead tour](lead.md#lead-tour) section below and the [orchestrate](orchestrate.md#orchestrate)
|
|
108
|
+
page.
|
|
109
|
+
|
|
110
|
+
## lead tour
|
|
111
|
+
|
|
112
|
+
`cadence lead tour [folder] [--idle 3] [--depth n] [--json]` is the lead's morning table, with no model in
|
|
113
|
+
the loop. From a parent folder (default: the current one) it takes every direct sub-folder that
|
|
114
|
+
holds `docs/plan/raf.yaml`, or a `cadence.yaml` with a `plan:` key (a plan kept by another tool
|
|
115
|
+
included), and for each one reads the same facts as `cadence session start` — in-process, no
|
|
116
|
+
sub-process, no call to `claude` — then prints **one line per project**:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
alpha · en cours L1 (silencieux 4j) · dérive 1 (✗ L2 a 1 commit(s) mais est encore todo) · notes : finir L1 puis livrer · prochain L3 Typo · dépôt non commité, non poussé
|
|
120
|
+
beta · en cours rien · dérive aucune · notes : aucune · prochain T2 Second · dépôt propre
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
| Column | Content |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `en cours` | ids of the lots in progress; `(aucune activité)` when it has none at all, `(silencieux Nj)` when the lot's last activity (commit, note or start) is more than `--idle` days old (default 3) |
|
|
126
|
+
| `dérive` | the gaps `raf check` reports (a lot whose commits leave a document behind, [`docs.sync`](news.md#documentation-that-follows-the-code), included), counted and the first two shown |
|
|
127
|
+
| `notes` | the notes left by the last `session close`, joined with ` / ` and cut at 120 characters |
|
|
128
|
+
| `prochain` | the first ready lot (quick wins first) — id and title cut at 60 characters; a lot whose [`gate`](raf.md#plan-file) is not met is not ready |
|
|
129
|
+
| `attend` | only when a lot waits on its `gate`: `attend L190` |
|
|
130
|
+
| `dépôt` | `non commité` (modified or untracked files), `non poussé` (commits ahead of the upstream), `livraison en cours` (live delivery lock); `propre` otherwise |
|
|
131
|
+
|
|
132
|
+
When an orchestrated wave is live, one more line closes the tour (not part of `--json`): `vagues en cours : 1 · sessions en cours : 0 · créneaux libres : 1 sur 2` — the lead reads the free slots there instead of computing them (L141). The `sur M` is the cap the human set (`CADENCE_MAX_SESSIONS`, 2 by default), not a fixed 2 (L208); an invalid value falls back to 2 in this display.
|
|
133
|
+
|
|
134
|
+
`--json` prints the same content as an array of objects (`project`, `doing`, `drift`, `notes`, `waiting` (only when a lot waits on its `gate`),
|
|
135
|
+
`next`, `repo`, and `error` when the project could not be read), plus `progress` — `{ done, doing, todo, added7 }`,
|
|
136
|
+
the lots done / in progress / to do (dropped and recurring lots left out) and those created in the last 7 days (L149), which
|
|
137
|
+
[`cadence-hud`](../plugins/cadence-hud/README.md) draws as one progress bar per project. Projects come in the order of the
|
|
138
|
+
`priority:` key of the folder's `cadence.yaml` (the one `orchestrate --continue` reads), the others after, alphabetically; an unreadable `cadence.yaml` or
|
|
139
|
+
a `priority:` that is not a list of names (`priority: ol`, `priority: []`) keeps the alphabetical order and adds a first row `cadence.yaml · ✗ erreur : <cause>` (`project: "cadence.yaml"` with `error` in `--json`).
|
|
140
|
+
Sub-projects are looked for one level down by default. `--depth n` goes `n` levels down (same meaning as in `cadence session start --all --depth n`:
|
|
141
|
+
a folder that is a project is not entered; an integer ≥ 1, otherwise refused), and the `depth:` key of the folder's `cadence.yaml`, next to `priority:`, sets it once for all
|
|
142
|
+
(`depth: 2`); `--depth` wins over the key, and a `depth:` that is not an integer ≥ 1 adds the same first row `cadence.yaml · ✗ erreur : …` and leaves one level read.
|
|
143
|
+
`cadence-hud` asks the tour from the folder of the session, so it follows the key with no change. A project is named by its folder's name; one found below the first level is named by its path from the folder (`groupe/gamma`), unique and ready for `cadence orchestrate groupe/gamma:L1` run from there, while `priority:` and the alphabetical order read the folder's own name.
|
|
144
|
+
"Created in the last 7 days" means today and the six days before. When the folder has no sub-project but is itself a project, the tour is that project's single line
|
|
145
|
+
(this is what `cadence-hud` asks from a session opened inside a project). The tour is read-only: it changes
|
|
146
|
+
no plan. It exits 0 even when a project is in error — that project's line reads
|
|
147
|
+
`beta · ✗ erreur : <cause>`. The `lead` skill runs it instead of one subagent per project.
|
package/docs/news.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
[← cadence](../README.md)
|
|
2
|
+
|
|
3
|
+
# news
|
|
4
|
+
|
|
5
|
+
What changed *for the user*, one entry per visible lot, each with a screenshot.
|
|
6
|
+
|
|
7
|
+
- Mark a lot as user-facing with `raf add … --visible` (or `visible: true` in
|
|
8
|
+
the YAML). `raf done` and the post-commit hook remind you to write its entry;
|
|
9
|
+
`raf check` fails while a visible lot is done without one.
|
|
10
|
+
- An entry is a Markdown file in `docs/nouveautes/`, with a YAML header.
|
|
11
|
+
Screenshots are files you take yourself, stored next to the entries.
|
|
12
|
+
- `cadence news build` writes `nouveautes.json` for your app to display, a
|
|
13
|
+
self-contained `index.html`, and copies the screenshots.
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
raf add "Amounts like 3.000 read as three thousand" --visible # → L8
|
|
17
|
+
raf start L8 && git commit -m "fix(L8): thousands separator" && raf done L8
|
|
18
|
+
cadence news new L8 # docs/nouveautes/2026-09-29-amounts-like-3-000-….md (title: the lot's public title if any)
|
|
19
|
+
# add docs/nouveautes/captures/l8.png, list it under `captures:`, write the text
|
|
20
|
+
cadence news check # exit 1 on drift (also part of raf check)
|
|
21
|
+
cadence news build -o frontend/public/nouveautes
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
---
|
|
26
|
+
title: Amounts like 3.000 read as three thousand
|
|
27
|
+
date: 2026-09-29
|
|
28
|
+
created: 2026-09-29T14:32+02:00
|
|
29
|
+
lots: [L8]
|
|
30
|
+
captures: [captures/l8.png]
|
|
31
|
+
# nocapture: reason, when a screenshot makes no sense
|
|
32
|
+
---
|
|
33
|
+
Imported statements now read **3.000** as three thousand, not three.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
A screenshot can say what it shows: write it as `{ file, alt }` instead of a
|
|
37
|
+
bare path, one text per screenshot.
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
captures:
|
|
41
|
+
- { file: captures/l8-before.png, alt: "Statement total read as 3 instead of 3,000" }
|
|
42
|
+
- captures/l8-after.png # a bare path still works: no alternative text
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Command | Effect |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `cadence news new <lot…> [--title t]` | entry skeleton, dated and timed now (`date`, `created`), titled after the lot's public title (`public`), else its title; `--title` wins |
|
|
48
|
+
| `cadence news list` | entries, newest first (see *Order* below) |
|
|
49
|
+
| `cadence news check` | visible lots done without entry, unknown lots, missing or undeclared screenshots, entries without creation time, bad headers, a lot whose screen sheet has hypotheses and whose entry lacks the `## Hypothèses` section (or a line for one of them) |
|
|
50
|
+
| `cadence news stamp` | migration: writes `created:` into entries without one (or with an empty one), from the author date of the commit that added the file under its current name (now if not committed yet) |
|
|
51
|
+
| `cadence news build [-o dir]` | `nouveautes.json` + `index.html` + screenshots (default `docs/nouveautes/site`) |
|
|
52
|
+
|
|
53
|
+
`--dir` changes the entries folder (default `docs/nouveautes` at the git root).
|
|
54
|
+
The Markdown is deliberately small: headings (`#` to `######`, rendered one level lower, `<h2>` to `<h6>`; a heading takes its own line and cuts the paragraph or list around it), paragraphs, `-` lists (a bullet may continue on the next lines, indented), `**bold**`,
|
|
55
|
+
`` `code` ``, `[links](../url)`; everything else is escaped text. The JSON holds
|
|
56
|
+
`{ project, generated, entries: [{ slug, title, date, lots, captures, html }] }`,
|
|
57
|
+
with screenshot paths relative to the JSON file. `captures` is always a list of
|
|
58
|
+
paths; an entry that gives at least one alternative text also carries `alts`,
|
|
59
|
+
the texts in the same order (`""` for a screenshot without one) — an entry
|
|
60
|
+
without any keeps exactly the shape above. The built page puts the text in the
|
|
61
|
+
image's `alt`, and falls back to "Capture : <title>".
|
|
62
|
+
|
|
63
|
+
**Order.** Everywhere (`list`, `build`, the JSON), entries are strictly newest
|
|
64
|
+
first: by `date`, then, on the same day, by creation time. Every entry carries
|
|
65
|
+
it to the minute in its `created` header, which `cadence news new` writes as
|
|
66
|
+
local time with an explicit offset (`2026-09-29T14:32+02:00`, or `Z`). The
|
|
67
|
+
offset is required, so the order does not depend on the machine's time zone:
|
|
68
|
+
`news check` (and `raf check`) flags a value without it, an impossible one, an
|
|
69
|
+
empty `created:`, and an entry without `created`. `cadence news stamp` fills
|
|
70
|
+
it in older entries (or replaces an empty one) from the author date of the
|
|
71
|
+
commit that added the file under its current name; until then, that date is
|
|
72
|
+
used for sorting (an entry not committed yet counts as the newest). Renames
|
|
73
|
+
are not followed: a renamed entry counts as added on the day of the rename,
|
|
74
|
+
so stamp it before renaming it. The file name only breaks the remaining ties,
|
|
75
|
+
since it follows the title, not the chronology. The page and the JSON still
|
|
76
|
+
show the day only.
|
|
77
|
+
|
|
78
|
+
## UX review
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
raf ux enable # from today, a --visible lot needs a UX review before done
|
|
82
|
+
raf ux L4 "compliant after 2 fixes" # record the verdict (from the ux-reviewer agent)
|
|
83
|
+
raf ux L8 "no screen: calculation fix"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
With the rule on, `raf done` refuses a visible lot without a review (`--force`
|
|
87
|
+
to override) and `raf check` reports visible lots finished after the `uxSince`
|
|
88
|
+
day without one. An empty verdict is refused, and one left empty or blank by hand
|
|
89
|
+
in the YAML counts as no review. Plans without `uxSince` are not affected.
|
|
90
|
+
|
|
91
|
+
## Code review
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
raf review enable # from today, a lot with commits needs a code review before done
|
|
95
|
+
raf commits L4 # what there is to review: the commits the gate counts for the lot
|
|
96
|
+
raf review L4 "compliant after 2 fixes" # record the verdict (from the code-reviewer agent)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The counterpart of the UX review, off by default. With the rule on, `raf done`
|
|
100
|
+
refuses a lot that has at least one commit citing it and no recorded verdict
|
|
101
|
+
(`--force` to override), and `raf check` reports such lots finished after the
|
|
102
|
+
`reviewSince` day. A lot with no commit has nothing to review; neither does a
|
|
103
|
+
lot whose only commits touch plan files alone (the plan, a file listed under
|
|
104
|
+
`plan.files`, or the QA expectations file), are version commits (see [Releasing](releasing.md#releasing)), predate the plan's `since` or match an `ignore:` pattern — `raf commits <id>` prints exactly the counted set.
|
|
105
|
+
|
|
106
|
+
The verdict is tied to what was reviewed: `raf review` stores it on the lot with
|
|
107
|
+
the sha of the lot's latest counted commit (`review: { date, verdict, commit }`,
|
|
108
|
+
`commit: null` when the lot had none). A counted commit made after that one
|
|
109
|
+
makes the review stale: `raf done` refuses (`--force` to override), and
|
|
110
|
+
`raf check` reports a finished lot, until the lot is reviewed again and
|
|
111
|
+
`raf review` is rerun. A verdict
|
|
112
|
+
written by hand without a `commit` field is not checked for staleness. An empty
|
|
113
|
+
verdict is refused, and one left empty or blank by hand in the YAML counts as no
|
|
114
|
+
review. Plans without `reviewSince` are not affected.
|
|
115
|
+
|
|
116
|
+
A lot that works in neighbouring repositories (`repos:`, see [orchestrate](orchestrate.md#a-lot-whose-work-is-in-a-neighbouring-repository))
|
|
117
|
+
has its verdict tied to each of them: `raf review` also stores, under `repos`, the sha of the latest counted commit of the
|
|
118
|
+
lot in each neighbour (the one `raf commits` lists last: it cites the lot, falls within the lot's period and contains the `cite:` string if any) (`review: { date, verdict, commit, repos: { ../aetherwx-gitops: <sha> } }`, `null` when a
|
|
119
|
+
neighbour has none), and refuses to record when a listed repository cannot be read. `raf check` does not audit the
|
|
120
|
+
neighbours: their staleness is not checked, only the project's own commits are.
|
|
121
|
+
|
|
122
|
+
## Documentation that follows the code
|
|
123
|
+
|
|
124
|
+
A stale README misleads. `cadence.yaml` can declare which documents must follow which code:
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
docs:
|
|
128
|
+
sync:
|
|
129
|
+
- paths: [src/**, bin/*.js] # what changes…
|
|
130
|
+
docs: [README.md, docs/usage.md] # …must change one of these, in the same lot
|
|
131
|
+
- paths: [templates/]
|
|
132
|
+
docs: [CLAUDE.md]
|
|
133
|
+
- paths: [frontend/src/**, '!**/*.test.tsx'] # a pattern starting with ! leaves files out
|
|
134
|
+
docs: [README.md]
|
|
135
|
+
since: 2026-10-09 # optional: also audit lots finished on or after this day
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
A pattern is an exact path, with `*` (inside a folder), `**` (across folders), `?`, or a trailing `/` for
|
|
139
|
+
a whole folder. `raf check` takes the **work commits** of every lot in progress (plan-only commits and
|
|
140
|
+
version commits do not count — so a "What's new" line written in the version commit is not documentation; a lot finished on or after `docs.since` is audited too) and, for each pair, reports the lot when
|
|
141
|
+
those commits touch `paths` without any of them touching a file of `docs`:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
✗ L7 : documentation en retard — src/a.ts, src/b.ts sans toucher README.md ou docs/usage.md (docs.sync)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
It counts as drift: exit code 1, shown in the `dérive` column of `cadence lead tour`, and the review
|
|
148
|
+
brief of `cadence orchestrate` (`review` and `review-small`) carries the list the program computed,
|
|
149
|
+
to be reported as one **major** finding per line — a stale document is not left to the reviewer's
|
|
150
|
+
memory of a sentence. Touching a document is what the program checks; whether its text is true is
|
|
151
|
+
still the review's reading. The commits of neighbouring repositories (`repos:`) are not audited.
|
|
152
|
+
|
|
153
|
+
### An article elsewhere that follows the delivery
|
|
154
|
+
|
|
155
|
+
A case study that lives in a neighbouring repository (the project's article on a showcase site) goes stale
|
|
156
|
+
the same way. `docs.articles` names it:
|
|
157
|
+
|
|
158
|
+
```yaml
|
|
159
|
+
docs:
|
|
160
|
+
articles:
|
|
161
|
+
- repo: ../claude-code-codex # neighbouring repository, relative to the project
|
|
162
|
+
file: src/pages/cas/demo.md # the article in it
|
|
163
|
+
name: demo # optional: the name in the lot title (default: the plan's project)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
After a **green** `cadence deliver`, for the lots it lists as delivered **that have a public title** (`public:`, or
|
|
167
|
+
the title of their Nouveautés entry), cadence opens in this repository's plan the lot
|
|
168
|
+
`Article demo à rafraîchir` (todo, estimate 0.5, `repos: [{ path: ../claude-code-codex, cite: demo }]`), with a note
|
|
169
|
+
that quotes the delivery, the public titles delivered, the article and the **sections to read again**: the headings
|
|
170
|
+
(`#` lines, or `<h1>`…`<h6>` of an Astro page) that share a word of five letters or more with a delivered title,
|
|
171
|
+
else all the `##` headings. The lot is then played like any other, in an ordinary wave (`cadence orchestrate`: an
|
|
172
|
+
implementer rewrites the article in the neighbouring repository, the review checks it against the note). If a lot
|
|
173
|
+
of that title is still open, it receives a note instead of a duplicate. Two entries with the same name (the same
|
|
174
|
+
project told in two neighbouring repositories) share one lot, which declares both repositories in `repos:`. Internal lots (no public title) open nothing;
|
|
175
|
+
a red delivery opens nothing; `cadence deliver --dry-run` announces the articles. The plan is written but **not
|
|
176
|
+
committed** (`deliver` never commits): the line `article à rafraîchir : L9 …` says so. With a plan kept by another
|
|
177
|
+
tool (read-only), the same line carries the instruction to open the lot with that tool. This replaces the manual
|
|
178
|
+
`sync-site-docs` skill.
|
|
179
|
+
|
|
180
|
+
## QA review
|
|
181
|
+
|
|
182
|
+
No gate and no command here: the QA review comes **after** a delivery, and
|
|
183
|
+
`raf done` does not wait for it. It follows any delivery that changes what a
|
|
184
|
+
page shows or what it is served (screen, API, data source, configuration of
|
|
185
|
+
either) — in practice every delivery except docs-, plan- or tests-only ones: a
|
|
186
|
+
backend-only lot can empty a page without touching a screen, and the agent then
|
|
187
|
+
walks the pages that call the changed endpoints. It also walks the pages that consume the services the lot changed; when the diff changes no route and no screen, or cannot be linked to pages, it walks every page and says so. The `qa-reviewer` agent
|
|
188
|
+
opens each page of the running app in a real browser and judges it from the
|
|
189
|
+
user's side. A page can be empty while everything else is green — no code
|
|
190
|
+
changed, a data source went down upstream, the unit tests replace the network,
|
|
191
|
+
`/api/health` answers ok, and the "nothing found" on screen is the message the
|
|
192
|
+
code was written to show.
|
|
193
|
+
|
|
194
|
+
The agent cannot tell such an empty state from a normal one by itself: the
|
|
195
|
+
project says what each page must show, in `docs/qa/expectations.md` — one
|
|
196
|
+
`## <route>` section per page, three kinds of lines:
|
|
197
|
+
|
|
198
|
+
```markdown
|
|
199
|
+
# QA expectations
|
|
200
|
+
|
|
201
|
+
## *
|
|
202
|
+
- shows: the header and the navigation links
|
|
203
|
+
- never: "Loading failed", "Too Many Requests"
|
|
204
|
+
- api: /api/live/current — may be empty when no match is within 24 hours
|
|
205
|
+
|
|
206
|
+
## /players
|
|
207
|
+
- shows: the squad of the last match — at least 11 players
|
|
208
|
+
- shows: the season statistics table, 8 columns — 1440 only
|
|
209
|
+
- never: "No recent line-up found"
|
|
210
|
+
- api: /api/squad/last — a non-empty list
|
|
211
|
+
|
|
212
|
+
## /fixtures/:id (the first match linked from /fixtures)
|
|
213
|
+
- shows: both team names, the date, the score once the match is played
|
|
214
|
+
- never: "Unknown match"
|
|
215
|
+
- api: /api/fixtures/:id
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
- `shows:` — content that must be present and non-empty, with a count where one exists;
|
|
219
|
+
- `never:` — texts that must not appear: error messages, and empty-state messages that mean
|
|
220
|
+
missing data;
|
|
221
|
+
- `api:` — the calls the page depends on: each must answer 2xx with a non-empty body (a 200 with
|
|
222
|
+
`[]`, `{}` or `null` is a failure, unless its line says `may be empty when …`).
|
|
223
|
+
|
|
224
|
+
An optional `## *` section holds what every page must show, never show and call. A line may end
|
|
225
|
+
with a condition in plain words, which the agent honours: `may be empty when …`, `1440 only`,
|
|
226
|
+
`390 only` (a line without a width holds at both). Content hidden on the phone by design is not a
|
|
227
|
+
defect unless a `shows:` line requires it at 390; content pushed outside the visible area (it
|
|
228
|
+
needs a sideways scroll) is reported as suspect and handed to `ux-reviewer` in one line.
|
|
229
|
+
|
|
230
|
+
The rest is free text, written for a reader: a line can be repeated, and a route with a parameter
|
|
231
|
+
names a real value to visit or says where to find one. The file can live elsewhere:
|
|
232
|
+
|
|
233
|
+
```yaml
|
|
234
|
+
# cadence.yaml
|
|
235
|
+
qa:
|
|
236
|
+
expectations: docs/quality/pages.md
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The agent reads that key, and so does `raf check`: a commit touching only that file is plan upkeep (no lot to cite, see above). Without an expectations file the agent walks
|
|
240
|
+
the routes it discovers and still runs its universal checks: an error shown, a failed API call
|
|
241
|
+
whose content is missing on screen, a broken or missing content image are defects with or without a
|
|
242
|
+
file; an empty 2xx body, like whatever else would need an expectation to judge, is suspect at most
|
|
243
|
+
(it may be a normal absence). For a route with a
|
|
244
|
+
parameter, it finds a real value in the app's links or its API responses and says how it built the
|
|
245
|
+
URL. The agent then returns a draft for you to correct — it never writes the file itself.
|