* fix(#3099): emit LAST_ACTIVITY_UNPARSEABLE diagnostic when last_activity is present but unparseable parseActivityTimestamp returned null for both absent AND present-but-unusable last_activity values, silently suppressing the idle-stranded recommendation. Per ADR-1411's amendment (corrupt is not absent), the fallback stays but a diagnostic is now emitted via the warnUnusableInput seam. - Added LAST_ACTIVITY_UNPARSEABLE to UNUSABLE_REASON enum + prose - Wired warnUnusableInput into detectSignals when lastActivityRaw is truthy but parseActivityTimestamp returned null - Updated UNUSABLE_REASON lock test - Added 5 regression tests (unusable→diagnostic, absent→silent, well-formed→silent, dedup) * chore(#3099): add changeset fragment * chore(#3099): backfill changeset PR number 3139 --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -51,6 +51,9 @@ const { stateExtractField } = stateDocument;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import phaseId = require('./phase-id.cjs');
|
||||
const { comparePhaseNum, extractPhaseToken, normalizePhaseName, phaseTokenMatches } = phaseId;
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import unusableInput = require('./unusable-input.cjs');
|
||||
const { warnUnusableInput, UNUSABLE_REASON } = unusableInput;
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -355,7 +358,16 @@ export function detectSignals(cwd: string, now: () => number = Date.now): SmartE
|
||||
// Stale = no recorded activity for IDLE_STALE_MS. Used only by idle-stranded.
|
||||
// Computed here (with the clock seam) so the pure classify() stays a function
|
||||
// of (signals, staleActivity) and detectSignals owns all disk reads.
|
||||
// #3099 (ADR-1411 amendment): if last_activity is present but unparseable,
|
||||
// emit a diagnostic so the silent fallback (stale_activity: false) is visible.
|
||||
// The fallback itself stays — continuity is correct, the silence was the defect.
|
||||
const lastActivityMs = parseActivityTimestamp(lastActivityRaw);
|
||||
if (lastActivityRaw && lastActivityMs === null) {
|
||||
warnUnusableInput({
|
||||
reason: UNUSABLE_REASON.LAST_ACTIVITY_UNPARSEABLE,
|
||||
source: paths.state,
|
||||
});
|
||||
}
|
||||
const staleActivity = lastActivityMs !== null && now() - lastActivityMs > IDLE_STALE_MS;
|
||||
|
||||
// Verify-failed may be signalled either by STATE.md status or by a failed
|
||||
|
||||
Reference in New Issue
Block a user