cclaw-cli 7.0.4 → 7.0.5

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.
@@ -838,15 +838,24 @@ async function persistEntry(root, runId, clean, event, options = {}) {
838
838
  // Rerecord semantics: replace any pre-existing row with the same spanId
839
839
  // (regardless of its status) so the legacy v1/v2 row is upgraded to v3
840
840
  // shape on disk. The append path keeps the historical dedup semantics:
841
- // an exact (spanId, status) duplicate is dropped to keep retried hooks
842
- // idempotent.
841
+ // an exact (spanId, status, phase) triple is dropped to keep retried hooks
842
+ // idempotent. Including \`phase\` in the dedup key is required because a
843
+ // single TDD slice-builder span legitimately emits FOUR rows with
844
+ // status=completed (one each for phase=red|green|refactor|doc); a
845
+ // dedup on (spanId, status) alone would silently drop GREEN/REFACTOR/DOC
846
+ // and leave the linter reporting tdd_slice_green_missing for slices
847
+ // whose work actually landed.
843
848
  if (options.replaceBySpanId) {
844
849
  ledger.entries = ledger.entries.filter((entry) => entry.spanId !== clean.spanId);
845
850
  ledger.entries.push(clean);
846
851
  ledger.runId = runId;
847
852
  ledger.schemaVersion = LEDGER_SCHEMA_VERSION;
848
853
  await writeDelegationLedgerAtomic(ledgerPath, ledger);
849
- } else if (!ledger.entries.some((entry) => entry.spanId === clean.spanId && entry.status === clean.status)) {
854
+ } else if (!ledger.entries.some((entry) =>
855
+ entry.spanId === clean.spanId &&
856
+ entry.status === clean.status &&
857
+ (entry.phase ?? null) === (clean.phase ?? null)
858
+ )) {
850
859
  ledger.entries.push(clean);
851
860
  ledger.runId = runId;
852
861
  ledger.schemaVersion = LEDGER_SCHEMA_VERSION;
@@ -1031,7 +1031,9 @@ export async function appendDelegation(projectRoot, entry) {
1031
1031
  stamped.fulfillmentMode = expectedFulfillmentMode(fallbacks);
1032
1032
  }
1033
1033
  }
1034
- if (prior.entries.some((existing) => existing.spanId === stamped.spanId && existing.status === stamped.status)) {
1034
+ if (prior.entries.some((existing) => existing.spanId === stamped.spanId &&
1035
+ existing.status === stamped.status &&
1036
+ (existing.phase ?? null) === (stamped.phase ?? null))) {
1035
1037
  return;
1036
1038
  }
1037
1039
  validateMonotonicTimestamps(stamped, prior.entries);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "7.0.4",
3
+ "version": "7.0.5",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {