Skip to content

Commit 5cf53c8

Browse files
danafitkowskiclaude
andcommitted
v2.9.34 — audit-ledger closure wave (4 closes + HS3 + CLAUDE.md contract)
Closes 4 of 7 carryover items from AUDIT_LEDGER_v2.9.34.md plus HS3: - HS3 / CLAUDE.md operating contract — repo-root contract with the 4 DoD criteria, hard-stop conditions, ledger operating rules, forbidden phrases, three-artifact /ship-audit output contract. - #9 / alert triage — ALERT_TRIAGE.md enumerates all 23 alerts of case 01-small-clean-baseline; single root cause (corpus harness does not pass cal_map; 9 forward + 14 backward fallback variants). - #10 / 1k DAG fixture — new case 13-large-1000-dag-branching: 10-phase diamond cascade, 5-way fan-out + 5-way fan-in per phase, 1020 acts / 1059 rels, strict-mode PASS. - #16 / crypto signoff stub — real Ed25519 sign/verify via Node built-in crypto, cpp-skill-manifest/v2 wire format, 7-sub-suite tamper test. - #17 / SOP checklist schema + validator — JSON Schema draft-07 + per-step semantic binding from FORENSIC_USE_SOP.md, 4-fixture regression test. Partial close (engineering only, P6-values still user-blocked): - #6 / P6 expected-value — validate-p6-comparison.js + 7-scenario test + schema doc + matrix-doc cleanup (stale row-14/15 refs removed). New release-blocking test gates wired into test:all: test:sop, test:crypto, test:p6-comparison, test:corpus-dag. Engine math unchanged. ENGINE_VERSION bumped 2.9.33 -> 2.9.34 in cpm-engine.js + package.json; python_reference/cpm.py bumped 2.9.27 -> 2.9.34 (7-version drift closed). 5 hard-coded version assertions in cpm-engine.test.js refreshed. 34 stale v2.9.33 doc refs swept to v2.9.34. All validation/**/engine-output.json + summaries regenerated under v2.9.34 stamp. release-evidence/v2.9.34/ packet committed (7 computed + 3 CI-pending stubs to populate post-tag-push). CHECK_RELEASE_EVIDENCE=1 npm run test:all green: 1128/1128 unit + 747/747 crossval + 4 pre-existing gates + 4 new gates. cpm-engine.js SHA-256: 5a6abd78fac05bde9951b17f9ca27d2fd163b85ef956df18ced84cc214cc1f78 python_reference SHA-256: fefc98115060ecc7aec6e9fe2cf01a758f795ccd35631b84d1e80e367e6b1f68 See CHANGELOG.md v2.9.34 entry for the full closure breakdown. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7b02c31 commit 5cf53c8

72 files changed

Lines changed: 64189 additions & 128 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,149 @@ A stray bridge tag `temp-deploy-bridge-2026-05-11` (unrelated to any CHANGELOG e
1212

1313
---
1414

15+
## v2.9.34 — 2026-05-24 — Audit-ledger closure wave + CLAUDE.md operating contract
16+
17+
Closes 4 of 7 carryover items from the `AUDIT_LEDGER_v2.9.34.md` v2.9.33-rollover plus the HS3 hard stop. Engine math byte-identical to v2.9.33; this is a docs + closures + test-gates release.
18+
19+
### HS closes (hard-stop conditions on the audit ledger)
20+
21+
- **HS3 / `CLAUDE.md` operating contract missing.** The v2.9.34 audit ledger
22+
referenced `CLAUDE.md` three times (lines 6, 27, 63) as the source of
23+
the four Definition-of-Done criteria, but no such file existed in the
24+
repo. `CLAUDE.md` now lives in the repo root with the DoD, status
25+
taxonomy, hard-stop conditions, ledger operating rules, forbidden
26+
phrases, and the three-artifact `/ship-audit` output contract. The
27+
file becomes the citable contract for every future ledger.
28+
29+
### Ledger-row closes
30+
31+
- **#9 / Alert investigation — 23 baseline alerts.**
32+
`validation/xer-corpus/cases/01-small-clean-baseline/ALERT_TRIAGE.md`
33+
enumerates all 23 alerts and identifies the single root cause: the
34+
corpus harness does not pass `cal_map` through `runEngineOnXer`, so
35+
the engine falls back to 7-day ordinal arithmetic and emits one
36+
alert per arithmetic site (9 forward variants + 14 backward
37+
variants = 23). Verification: `node scripts/verify-alert-triage-01.js`.
38+
- **#10 / 1k DAG fixture extension.** New corpus case
39+
`13-large-1000-dag-branching` — 10-phase diamond cascade, 5-way
40+
fan-out from each phase-start milestone + 5-way fan-in to each
41+
phase-end milestone, 1020 activities / 1059 relationships /
42+
strict-mode PASS. Closes the "trivial FS chain only" gap on the
43+
existing 1k case (#02). Topology regression in
44+
`tests/corpus-dag-fixture.test.js`.
45+
- **#16 / Cryptographic analyst signoff stub + schema v2.**
46+
`scripts/crypto-signoff.js` ships real Ed25519 signing + verification
47+
via Node's built-in `crypto` (zero external deps). The
48+
`cpp-skill-manifest/v2` wire format documented at
49+
`docs/crypto-signoff-schema-v2.md` covers canonicalization, threat
50+
model, and the forward path to Sigstore Rekor (stubbed — the
51+
transparency block carries a documented `_note` placeholder).
52+
7-sub-suite regression: round-trip, payload tamper, signature
53+
zeroing, public-key swap, full key swap, schema mismatch,
54+
cross-keypair. Test gate `test:crypto`.
55+
- **#17 / Machine-readable SOP checklist + validator.**
56+
`schemas/sop-checklist.schema.json` (JSON Schema draft-07) +
57+
`scripts/validate-sop.js` (per-step semantic binding from
58+
FORENSIC_USE_SOP.md's "Capture in manifest" sections) +
59+
`validation/sop-examples/` (template, passing, failing fixtures).
60+
Documentation at `docs/sop-checklist-schema.md`. 4-fixture regression
61+
gate `test:sop`.
62+
63+
### Partial close — engineering portion only
64+
65+
- **#6 / P6 expected-value population.** Engineering scaffolding shipped:
66+
`scripts/validate-p6-comparison.js` validates each `comparison.csv`
67+
for header schema, engine-column accuracy against the case's
68+
`engine-output.json`, P6-discipline (all-filled or all-blank, no
69+
partial), and verdict-format grammar (`PASS` or `FAIL — <delta>`).
70+
7-scenario regression `tests/p6-comparison-validator.test.js`.
71+
Matrix-doc cleanup: stale row-14/15 references removed from
72+
`validation/p6-comparison/comparison-matrix.md` after their move to
73+
`validation/engine-limitations/` in the v2.9.33 audit cycle.
74+
Schema doc at `docs/p6-comparison-schema.md`. The P6-VALUES portion
75+
(filling `*_p6` columns from native P6 capture) remains user-blocked
76+
on Dana's P6 access.
77+
78+
### Carryover (unchanged status)
79+
80+
- **#5 / Third-party reproduction memo** — BLOCKED on identifying an
81+
outside reviewer.
82+
- **#8 / Real-XER sourcing** — ACCEPTED-LIMITATION; requires client
83+
consent.
84+
85+
### New test gates (release-blocking, wired into `test:all`)
86+
87+
- `test:sop``tests/sop-validator.test.js`
88+
- `test:crypto``tests/crypto-signoff.test.js`
89+
- `test:p6-comparison``tests/p6-comparison-validator.test.js`
90+
- `test:corpus-dag``tests/corpus-dag-fixture.test.js`
91+
92+
`scripts/attestation.js` continues to invoke the 5 pre-existing gates
93+
(unit, crossval, citation, truncation, version-drift); the new gates
94+
are exercised by `npm run test:all` separately. A v2.9.35+
95+
enhancement may extend `attestation.js` to include the new gates in
96+
the witness JSON; not in scope for this release.
97+
98+
### Engine code
99+
100+
- `cpm-engine.js:151``ENGINE_VERSION` bumped `'2.9.33'``'2.9.34'`.
101+
No math-side edits. SHA-256 rotates as a consequence of the string
102+
bump.
103+
- `python_reference/cpm.py:91``ENGINE_VERSION` bumped from a stale
104+
pin (had not been updated since the v2.9.27 audit cycle — 7-version
105+
drift). Behaviorally byte-identical; crossval 747/747 holds.
106+
107+
### Tests modified
108+
109+
- `cpm-engine.test.js` — 5 hard-coded `=== '2.9.33'` assertions
110+
refreshed to `'2.9.34'` (lines 1316, 1353, 1606, 2065, 2085).
111+
- `cpm-engine.test.js` SECTION R historical narration preserved
112+
(v2.9.33 section header references intentionally retained).
113+
114+
### Files added (17 new)
115+
116+
`CLAUDE.md`, `schemas/sop-checklist.schema.json`, `scripts/validate-sop.js`,
117+
`scripts/crypto-signoff.js`, `scripts/verify-alert-triage-01.js`,
118+
`scripts/validate-p6-comparison.js`, `tests/sop-validator.test.js`,
119+
`tests/crypto-signoff.test.js`, `tests/corpus-dag-fixture.test.js`,
120+
`tests/p6-comparison-validator.test.js`,
121+
`validation/sop-examples/{01-template-blank,02-passing-fully-filled,03-failing-incomplete}.json`,
122+
`validation/xer-corpus/cases/13-large-1000-dag-branching/{case.xer, engine-output.json, README.md}`,
123+
`validation/xer-corpus/cases/01-small-clean-baseline/ALERT_TRIAGE.md`,
124+
`docs/sop-checklist-schema.md`, `docs/crypto-signoff-schema-v2.md`,
125+
`docs/p6-comparison-schema.md`, `release-evidence/v2.9.34/`.
126+
127+
### Files modified
128+
129+
`package.json` (version + test gates + files list), `cpm-engine.js`
130+
(ENGINE_VERSION), `python_reference/cpm.py` (ENGINE_VERSION),
131+
`cpm-engine.test.js` (5 assertion refreshes),
132+
`validation/xer-corpus/generate-corpus.js` (case 13 + helper),
133+
`validation/p6-comparison/comparison-matrix.md` (row cleanup +
134+
version stamps), all `validation/**/engine-output.json` +
135+
`corpus-summary.json` + `engine-outputs-summary.json` (regenerated
136+
under new engine version stamp), `ROADMAP_OPEN.md` (status flips for
137+
#9 / #10 / #16 / #17), and version-header sweep across README,
138+
DAUBERT, VERIFY_RELEASE, FORENSIC_USE_SOP, docs/jurisdictions,
139+
docs/api, validation/p6-comparison/README, validation/xer-corpus/README.
140+
141+
### Verification chain
142+
143+
```
144+
Tag: v2.9.34
145+
Engine SHA-256: 5a6abd78fac05bde9951b17f9ca27d2fd163b85ef956df18ced84cc214cc1f78
146+
Python ref SHA-256: fefc98115060ecc7aec6e9fe2cf01a758f795ccd35631b84d1e80e367e6b1f68
147+
Unit tests: 1,128 / 1,128
148+
Crossval: 747 / 747 across 43 fixtures
149+
New gates: 4 / 4 (sop, crypto, p6-comparison, corpus-dag)
150+
npm run verify: PASS
151+
npm run test:all: PASS
152+
```
153+
154+
Sigstore Rekor entry + GitHub Actions workflow URL populate post-tag.
155+
156+
---
157+
15158
## v2.9.33 — 2026-05-24 — Audit-response wave pass 2 (closes ChatGPT fourth-pass findings)
16159

17160
Fourth-pass ChatGPT audit on v2.9.32 surfaced 19 items. v2.9.33 closes 14

CLAUDE.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# CLAUDE.md — Operating contract for `cpp-cpm-engine` releases
2+
3+
This file is the contract that the per-version `AUDIT_LEDGER_v{X}.md` files cite. It defines what "CLOSED" means, what hard-stop conditions block a release, and what the operator (a human or an AI agent like Claude Code) must do before claiming an audit row is closed.
4+
5+
If the ledger and this file disagree, **this file wins**. The ledger refers to this file; it does not redefine it.
6+
7+
---
8+
9+
## 1. Definition of Done (DoD) — the four criteria
10+
11+
A row in any `AUDIT_LEDGER_v{X}.md` may move to status **CLOSED** if and only if **all four** of the following are true:
12+
13+
1. **Code or doc change exists.** A concrete, committable diff — a new file, an edit to an existing file, or a configuration change — addresses the finding. Adding the item to `ROADMAP_OPEN.md` is *not* a change for this purpose; it closes the meta-tracking task only.
14+
2. **Verification command provided.** The ledger row's **Verification command** column contains a single shell or `node` command that an independent operator can run, in the repo root, to reproduce the verification. The command must exit non-zero on regression.
15+
3. **File read end-to-end after edit.** After the diff is written, the author re-reads the touched file(s) from line 1 to EOF — not by `grep`, not by pattern-match. This is the human-eye check that the change is internally consistent, that no leftover scaffolding remains, and that the surrounding context still parses.
16+
4. **Clean-window re-grep performed.** From a fresh read, search every touched file for: outdated version strings, contradictory test counts / metric values, references to evidence packets or fixtures that do not exist on disk, and forbidden marketing language ("industry-first", "best-in-class", "revolutionary", "world-class", "game-changing", "unprecedented", "cutting-edge", "state-of-the-art"). Any finding downgrades the row to DEFERRED until resolved.
17+
18+
A row that satisfies 3 of 4 is not CLOSED. There is no partial credit.
19+
20+
---
21+
22+
## 2. Status taxonomy (mirrored in every ledger)
23+
24+
- **CLOSED** — Four DoD criteria satisfied.
25+
- **DEFERRED** — Could be done with the available tools and context; not done this session. The row must state an effort estimate and confirm no structural blocker.
26+
- **ACCEPTED-LIMITATION** — Structural reason this cannot be done unaided. Allowed reasons: client consent, credentials, third-party action, missing physical access. The row must name the structural reason.
27+
- **BLOCKED** — Requires a specific user action named in the row (e.g., "Dana to identify reviewer").
28+
- **OBSOLETE** — Item no longer relevant. Row must include the reason. Row is never deleted.
29+
30+
The four are mutually exclusive. Every row is in exactly one state.
31+
32+
---
33+
34+
## 3. Hard-stop conditions before any release
35+
36+
A release may not proceed (no version bump, no release notes, no tag) if any of the following is true:
37+
38+
1. Any ACCEPTED-LIMITATION row lacks a structural reason from the allowed list.
39+
2. Any CLOSED row's Verification command failed or was not run.
40+
3. Any file touched in the release contains a Step-3 re-grep finding (stale version, contradiction, missing artifact reference, or marketing language).
41+
4. Any CLOSED row has empty Evidence or Verification command cells.
42+
5. Any row's Status column conflicts with its Verification result column (e.g., status = CLOSED but result describes a failure).
43+
44+
Hard stop #4 applies only to CLOSED rows. DEFERRED / ACCEPTED-LIMITATION / BLOCKED rows are expected to have empty Evidence / Verification cells until the underlying work happens.
45+
46+
---
47+
48+
## 4. Operating rules for ledgers
49+
50+
1. No row may move to CLOSED without satisfying §1.
51+
2. No row may be deleted. If it becomes irrelevant, mark OBSOLETE with a reason in the Verification result column.
52+
3. The `/ship-audit` command writes the final Status and Verification result columns. Do not pre-fill those during work — they get filled at verification time, not edit time.
53+
4. If a DEFERRED item is completed during the session: update Evidence + Verification command columns in place, leave Status as DEFERRED, and re-run `/ship-audit` to validate the closure.
54+
5. Adding an item to `ROADMAP_OPEN.md` is **not** closure. It closes the meta-tracking task; the underlying item stays DEFERRED until §1 is satisfied.
55+
6. If a verification command's output exceeds 100 lines, summarize to head + tail + total line count and link to the full output in `VERIFICATION_LOG_v{X}.md`.
56+
57+
---
58+
59+
## 5. Forbidden phrases in `/ship-audit` summary output
60+
61+
The closing summary must use the honest tally from `/ship-audit` Step 4. It may not use any of:
62+
63+
- "All items addressed"
64+
- "Audit closed"
65+
- "Substantially complete"
66+
- "Effectively done"
67+
- "Tracked for follow-up" (as a substitute for DEFERRED)
68+
69+
These phrases are forbidden because they have historically been used to claim closure without the underlying DoD work being done. The honest tally — "X CLOSED, Y DEFERRED, Z ACCEPTED-LIMITATION, W BLOCKED" — is always available and always acceptable.
70+
71+
---
72+
73+
## 6. Three artifacts at session end
74+
75+
Every `/ship-audit` run produces exactly three artifacts:
76+
77+
1. Updated `AUDIT_LEDGER_v{X}.md` with verified statuses, tally section filled, per-row Verification result column annotated with the audit-date note.
78+
2. New or updated `VERIFICATION_LOG_v{X}.md` containing the Step 2 command outputs and Step 3 re-grep findings.
79+
3. A one-paragraph summary delivered to the operator stating the honest tally and naming the top deferred items by number and effort estimate.
80+
81+
The operator writes release notes after reviewing those artifacts. `/ship-audit` does not write release notes.
82+
83+
---
84+
85+
## 7. Test gates and regression protection
86+
87+
Every release ships these test gates (run by `npm run test:all`):
88+
89+
- `npm test``cpm-engine.test.js` unit suite.
90+
- `npm run crossval``cpm-engine.crossval.js` JS/Python parity matrix.
91+
- `npm run test:cites``tests/no-fabricated-citations.test.js` (citation provenance).
92+
- `npm run test:truncation``tests/no-truncation.test.js` (no user-facing data truncation).
93+
- `npm run test:version-refs``tests/no-stale-version-refs.test.js` (no version-drift in docs).
94+
95+
New release-blocking gates added in v2.9.34:
96+
97+
- `tests/sop-validator.test.js` — machine-readable SOP checklist schema is honored by skill_manifest bindings.
98+
- `tests/crypto-signoff.test.js` — analyst-signoff stub round-trips sign → verify cleanly and rejects tampered manifests.
99+
100+
The `scripts/attestation.js` entrypoint must invoke every gate above; a release tag is forbidden if any gate fails.
101+
102+
---
103+
104+
## 8. Citation provenance
105+
106+
This contract is referenced by `AUDIT_LEDGER_v{X}.md` files in the repo root. If a future audit run cannot locate `CLAUDE.md` in the repo root, that is itself a Step-3 finding (HS3) and the release is blocked.
107+
108+
---
109+
110+
## 9. Document version
111+
112+
- Created: 2026-05-24 (v2.9.34 audit cycle).
113+
- Closes Hard Stop #3 of `AUDIT_LEDGER_v2.9.34.md` (missing contract document).
114+
- Update on every release that changes any rule above.

DAUBERT.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Daubert / FRE 702 Disclosure — `cpm-engine` v2.9.33
1+
# Daubert / FRE 702 Disclosure — `cpm-engine` v2.9.34
22

33
This is a formal disclosure for the engine itself, modeled on the structured output of `buildDaubertDisclosure()`. It is intended for use as a starting point in expert-witness exhibits and FRCP 26(a)(2)(B) reports under the *Daubert v. Merrell Dow Pharmaceuticals* (1993) framework as codified in Federal Rule of Evidence 702 (Dec 1, 2023 amendment), and is forward-compatible with proposed FRE 707.
44

@@ -176,7 +176,7 @@ Every `computeCPM` result carries a `manifest` block:
176176

177177
```js
178178
result.manifest = {
179-
engine_version: '2.9.33', // Synchronized with package.json (bump per release)
179+
engine_version: '2.9.34', // Synchronized with package.json (bump per release)
180180
method_id: 'computeCPM', // 'computeTIA', 'computeCPMSalvaging', etc.
181181
activity_count: 282,
182182
relationship_count: 421,
@@ -243,7 +243,7 @@ The engine and the validation suite were developed by the same author (Dana Fitk
243243
## Disclosure format version
244244

245245
`disclosure_format_version: 1.0`
246-
`engine_version: 2.9.33`
246+
`engine_version: 2.9.34`
247247
`generated_at:` (will be filled in by `buildDaubertDisclosure()` at runtime; this static document is dated 2026-05-24, refreshed for v2.9.33 audit-response-pass-2. v2.9.33 fixes the fatal-tier audit findings v2.9.33 still left open (VERIFY_RELEASE.md test-count contradictions, missing release-evidence packets, SHA-sidecar wording, attestation script not wiring the new gates) plus the medium-tier residuals (jurisdictions bottom guarantee section, "no silent wrong-answer paths" absolute language, dead-context test strengthening, structured override fields with backward compat, README competitor-table removal, machine-readable SOP-checklist binding). Prior milestones preserved: v2.9.33 audit-response wave + version-drift regression gate + computeCPMSalvaging strict-mode refusal; v2.9.31 Section Q Forensic Strict Mode public API + 33 strict-mode unit tests; v2.9.27 audit closeout + crossval 444→747; v2.9.12 Round 9 engine math fix wave; v2.9.11 Round 7 independent-verification infrastructure tag; v2.9.9 full hammock SS/FF/SF semantics; v2.9.10 Round 7-8 independent-verification stack (public CI, Sigstore attestation, one-command local reproduction).)
248248

249249
---
@@ -314,7 +314,7 @@ The engine honors the following Primavera P6 constraint types declared on activi
314314

315315
**Semantics.** Forward-pass clamps emit `{severity:'WARN', context:'constraint-applied'}`; impossibility-of-satisfaction cases emit `{severity:'ALERT', context:'constraint-violated'}`. Hammock-cycle topology emits `{severity:'ALERT', context:'hammock-cycle'}`. Hammock negative-span emits `{severity:'ALERT', context:'hammock-negative-span'}`. No silent-wrong-answer paths — every constraint that affects ES/EF/LS/LF, and every hammock anomaly, appears in `result.alerts`.
316316

317-
**Disclosure.** Opposing experts can audit every constraint applied during a run by filtering `result.alerts` on the contexts above. Pair with `result.manifest.engine_version === '2.9.33'` to confirm the constraint module version.
317+
**Disclosure.** Opposing experts can audit every constraint applied during a run by filtering `result.alerts` on the contexts above. Pair with `result.manifest.engine_version === '2.9.34'` to confirm the constraint module version.
318318

319319
**v2.9.12 — Round 9 engine math fix wave.** The audit memo identified ~30 substantive math defects across constraint handling, calendar arithmetic, in-progress + actuals, and JS/Python parity. T1.1 added MS_Start hard-pin on backward LF clamp (was JS+Python silent gap). T1.2-T1.3 emit `constraint-noop` WARN and suppress ES-side constraint clamps when an `actual_start` is present (AACE 29R-03 §4.3 immutability — both engines). T1.4 added Section D actual_start pinning with one-time `actual-start-not-anchored` WARN when `projectStart` is missing. T1.5 surfaces TT_LOE/TT_WBS/completed/zero-remaining drops + dangling-relationship drops + non-finite-lag rejections as INFO/ALERT alerts. T1.6 emits `constraint-unrecognized` / `constraint-incomplete` WARN on unknown tokens / missing dates. T1.7 added `CS_MANSTART` / `CS_MANFINISH` aliases. T1.8-T1.10 added Section D SNLT/FNLT/MS_Start violated+applied alerts symmetric with Section C. T2.11 rewrote Free Float on the binding-link's calendar so coincident lag-walked-forward pairs produce 0 slack. T2.12 made `_countWorkDaysBetween` signed (preserves negative-float forensic signal). T2.13 removed the `Math.max(0, ...)` FF clamp. T2.14 added `dateToNum` rollover guard (Feb 30 → 0 instead of silent rewrite to Mar 2). T2.15 rejects non-finite `lag_hr_cnt` from parseXER. T2.16 emits `invalid-calendar-falling-back` WARN when work_days is empty/invalid. T2.17 updated SUB_DAY_LAG_ROUNDED message to disclose V8 Math.round direction-bias. T3.18 added `remaining_duration` for P6 retained-logic EF anchoring. T3.19 pins LS=ES on backward pass when actual_start is present (in-progress, both engines). T3.20 guards `EF >= ES` in Section C EF-side helpers. T3.21 enumerates every unstarted predecessor + catches premature-start OoS. T3.22 emits `hammock-orphan` ALERT when no anchors resolve. T3.23 adds `duration_working_days` to hammocks. T3.24 emits `unrecognized-task-type` WARN. T4.25-T4.26 backport R8A-1 (MISSING_ACTUAL_START ES derivation) and ALAP-secondary-slot guard to the Python reference, rotating the SHA-256 pin. T4.27 was already in place on the JS side from T1.3.
320320

0 commit comments

Comments
 (0)