@afokapu/atdd-bun 0.10.2 → 0.10.3
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/README.md
CHANGED
|
@@ -160,6 +160,10 @@ From 0.10.2 the pre-commit hook no longer counts uncommitted work: it refused ex
|
|
|
160
160
|
commits that reduce it. `max_uncommitted_files` is no longer read; commit size stays limited by
|
|
161
161
|
`max_staged_files` and `max_staged_changed_lines`.
|
|
162
162
|
|
|
163
|
+
From 0.10.3 each ready record is judged by the delivery policy in `atdd-bun.yaml` at its `approved_sha`:
|
|
164
|
+
a later policy change (dropping or reordering a model, removing a review) never makes a merged record
|
|
165
|
+
fail. Records in progress are judged by the current policy.
|
|
166
|
+
|
|
163
167
|
Every key is optional; these are the defaults:
|
|
164
168
|
|
|
165
169
|
```yaml
|
|
@@ -17,6 +17,8 @@ content:
|
|
|
17
17
|
fix_hint: |
|
|
18
18
|
Run the missing review, or set status back to open until it has run. Set approved_sha to the SHA the final review approved.
|
|
19
19
|
exceptions:
|
|
20
|
+
- >-
|
|
21
|
+
A ready record is judged by the policy in atdd-bun.yaml at its approved_sha, the policy it was approved under; a later policy change does not re-judge it. A record in progress is judged by the current policy.
|
|
20
22
|
- >-
|
|
21
23
|
A stage the policy omits is not required. Omitting one loosens the policy and is reported by the integrity check until a human approves it.
|
|
22
24
|
metadata:
|
package/integrity.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.10.
|
|
2
|
+
"version": "0.10.3",
|
|
3
3
|
"files": {
|
|
4
4
|
"HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
|
|
5
5
|
"PLANNER_PORT.md": "fb5935bac8b7ac18994de21e43ace3a5ef8cd55f85b0e3349fca261280054f11",
|
|
6
|
-
"README.md": "
|
|
6
|
+
"README.md": "cb2d6e38a9375242be1b77453082ec835120cd19946af0f73293ae801d21c1dd",
|
|
7
7
|
"bunfig.toml": "b9fc65eca9014c5179380259d70e76385a6a80788fa9a2df5fb3eaa5554fd2fe",
|
|
8
8
|
"conventions/atdd-bun.planner/atdd-bun.planner.acceptance-identity.convention.yaml": "81c5c773d5ee15e8d99a2c237aa9846b110b2533df45ebf407d0e3ec6ed3dd03",
|
|
9
9
|
"conventions/atdd-bun.planner/atdd-bun.planner.identity-required.convention.yaml": "e96d7c1455d0c221072d82e7f2b55da1c4f9ceb17718eb6ed96affdeef37675b",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"conventions/delivery/delivery.operating-model.convention.yaml": "980858b735974093c98e850d8f6dd83cb21eea86a8b6e8249de678f0fc336f1b",
|
|
102
102
|
"conventions/delivery/delivery.review.convention.yaml": "d71b889a92ca695bc7bc989636ef16272860a4d3389a2f1e2cf3776257e97af8",
|
|
103
103
|
"conventions/delivery/delivery.reviewer-independent.convention.yaml": "264df63e768a2a17dca782dddbba6ba47a21fa3dd9cd39ed150f9a00dd04bdb0",
|
|
104
|
-
"conventions/delivery/delivery.stages-complete.convention.yaml": "
|
|
104
|
+
"conventions/delivery/delivery.stages-complete.convention.yaml": "18f1e1e4a4774cc922f9c86f5d08e0b3b1d992967816277066efec648741f71c",
|
|
105
105
|
"conventions/planner.docs/planner.docs.adr-registry-derived.convention.yaml": "0ea4232beba90280c664f93d097cafa44c67c2919c1468d4823fdc9e686aa5d2",
|
|
106
106
|
"conventions/planner.docs/planner.docs.area-index-required.convention.yaml": "fd931e9f225bfbb5e78436d0d8a2a89cc0f5114493579962c72dd971301becce",
|
|
107
107
|
"conventions/planner.docs/planner.docs.artifact-path-shape.convention.yaml": "a9f6178d29abe9385342a46a2c57470a3631aaf5e26f01e3660b7088b042418e",
|
|
@@ -1195,7 +1195,7 @@
|
|
|
1195
1195
|
"src/board.ts": "f04c425f74edc003609baec7b5b2d75c1bc98b0e177d702de865dd42d9dd95e5",
|
|
1196
1196
|
"src/ci.ts": "67e54d2cbfc44a9e42837d5e750af526d6255c539d3c452a4d5fca3226c0d9ac",
|
|
1197
1197
|
"src/cli.ts": "b1618d7a7b3b0d42238cb1160aea4ee7962fef8135a7c75b89b0f3fa30dc1f45",
|
|
1198
|
-
"src/delivery.ts": "
|
|
1198
|
+
"src/delivery.ts": "f36550be2a7e2f45a8026612b48542d040bb0ac27f7e950c91d980bc69763ddc",
|
|
1199
1199
|
"src/docs-capability.ts": "115cf27049a5cf19c133bac5ec237072be6f969a59a2ef6767e054108a21dc5c",
|
|
1200
1200
|
"src/enforce.ts": "41a6f8c058a2a034996c817f224191403cc66ccc4ed4e04bbefc430014c783d8",
|
|
1201
1201
|
"src/hooks.ts": "9779eb48f9d0cb6234c33f6616f98dde6583d2ee03ac3c19f3ace2d156af26d0",
|
package/package.json
CHANGED
package/src/delivery.ts
CHANGED
|
@@ -145,6 +145,18 @@ export function loosenedDelivery(base: unknown, current: unknown): string[] {
|
|
|
145
145
|
return out;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
/** The delivery policy a ready record was approved under: atdd-bun.yaml at its approved_sha. A merged record proves it met
|
|
149
|
+
* the policy of its time, so a later policy change never makes it fail. When that commit has no readable, adopting
|
|
150
|
+
* config, the current policy applies. The root stays today's: it only locates the records. */
|
|
151
|
+
async function policyAt(root: string, sha: string, current: DeliveryPolicy): Promise<DeliveryPolicy> {
|
|
152
|
+
const prefix = (await git(root, ["rev-parse", "--show-prefix"])).out, shown = await git(root, ["show", `${sha}:${prefix}atdd-bun.yaml`]);
|
|
153
|
+
if (shown.code) return current;
|
|
154
|
+
try {
|
|
155
|
+
const data = record(Bun.YAML.parse(shown.out));
|
|
156
|
+
return data && deliveryAdopted(data) ? { ...deliveryPolicy(data.delivery ?? {}), root: current.root } : current;
|
|
157
|
+
} catch { return current; }
|
|
158
|
+
}
|
|
159
|
+
|
|
148
160
|
async function readConfig(root: string): Promise<{ data: Record<string, unknown> | null; error?: string }> {
|
|
149
161
|
const file = join(root, "atdd-bun.yaml");
|
|
150
162
|
if (!existsSync(file)) return { data: null };
|
|
@@ -455,7 +467,8 @@ export async function validateDelivery(root = process.cwd(), options: DeliveryOp
|
|
|
455
467
|
if (seen.has(review.report)) findings.push(finding("delivery.evidence-schema", entry.file, `reviews[${index}] reuses report ${review.report} from reviews[${seen.get(review.report)}]; every review retains its own report`));
|
|
456
468
|
else seen.set(review.report, index);
|
|
457
469
|
}
|
|
458
|
-
|
|
470
|
+
const judged = entry.data.status === "ready" && entry.data.approved_sha ? await policyAt(absolute, entry.data.approved_sha, policy) : policy;
|
|
471
|
+
findings.push(...checkEvidence(entry.file, entry.data, judged));
|
|
459
472
|
if (entry.data.status === "ready") {
|
|
460
473
|
// Ready means auditable: every review's raw output is retained and named.
|
|
461
474
|
for (const [index, review] of entry.data.reviews.entries()) if (!review.report || !regularFile(join(absolute, review.report))) findings.push(finding("delivery.stages-complete", entry.file, `status is ready, but reviews[${index}] (${review.stage}) ${review.report ? `names report ${review.report}, which is not a regular file` : "retains no report"}`));
|
|
@@ -468,7 +481,7 @@ export async function validateDelivery(root = process.cwd(), options: DeliveryOp
|
|
|
468
481
|
else if (!await inHistory(item.sha)) findings.push(finding("delivery.approved-sha-resolves", entry.file, `work[${index}] (${item.stage}) names ${item.sha.slice(0, 7)}, which is not in the history of approved_sha ${approved.slice(0, 7)}`));
|
|
469
482
|
}
|
|
470
483
|
let previous: { stage: Stage; sha: string } | null = null;
|
|
471
|
-
for (const stage of STAGES.filter(name =>
|
|
484
|
+
for (const stage of STAGES.filter(name => judged.stages[name]?.reviewer.length)) {
|
|
472
485
|
const last = entry.data.reviews.filter(review => review.stage === stage).at(-1);
|
|
473
486
|
if (!last || last.verdict !== "approve") continue; // reported by delivery.stages-complete
|
|
474
487
|
if ((await git(absolute, ["cat-file", "-e", `${last.sha}^{commit}`])).code) { findings.push(finding("delivery.approved-sha-resolves", entry.file, `${stage} approved ${last.sha}, which is not a commit in this repository's history`)); continue; }
|