fix(#1831): resolve ESLint errors and unused-var warnings from #1829/#1830
Two hard errors in src/state-transition.cts: - reconcileCurrentPosition: `!== null` guards on `Record<string,unknown>` values don't narrow the type to a primitive, causing @typescript-eslint/no-base-to-string to fire on String(fm.current_phase) and String(fm.current_phase_name). Extract to typed locals + use typeof narrowing so the rule sees string | number — which is the actual invariant. Four unused-var warnings (warnings are still defects per RULESET): - stripTemplatePlaceholders: `placeholder` was assigned value.trim() but never read — the value came from the loop variable itself, so removed. - deduplicateSessionArchive: `sectionContent` was sliced but the filter below uses the raw hs offsets directly — variable was dead code; removed. - state-rebuild.test.cjs: first transitionCore call in the orphan-row test is covered by the dedicated Leaky-Abstractions guard test below it; remove the no-op call rather than silently ignoring its result. - state-rebuild.test.cjs: `before = state` in the sync regression guard test was never read — remove the dead assignment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1666,8 +1666,9 @@ function reconcileCurrentPosition(
|
|||||||
// by other transitions (beginPhase / completePhase) and reconstructed from
|
// by other transitions (beginPhase / completePhase) and reconstructed from
|
||||||
// total-phase counts; rebuild reconciles only the `**Current Phase:**` body
|
// total-phase counts; rebuild reconciles only the `**Current Phase:**` body
|
||||||
// field that frontmatter is the canonical source for.
|
// field that frontmatter is the canonical source for.
|
||||||
if (fm.current_phase !== undefined && fm.current_phase !== null) {
|
const fmPhase = fm.current_phase;
|
||||||
const canonicalPhase = String(fm.current_phase);
|
if (typeof fmPhase === 'string' || typeof fmPhase === 'number') {
|
||||||
|
const canonicalPhase = String(fmPhase);
|
||||||
const existing = stateExtractField(modified, 'Current Phase');
|
const existing = stateExtractField(modified, 'Current Phase');
|
||||||
if (existing !== null && existing !== canonicalPhase) {
|
if (existing !== null && existing !== canonicalPhase) {
|
||||||
const replaced = stateReplaceField(modified, 'Current Phase', canonicalPhase);
|
const replaced = stateReplaceField(modified, 'Current Phase', canonicalPhase);
|
||||||
@@ -1686,8 +1687,9 @@ function reconcileCurrentPosition(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Phase name prose.
|
// Phase name prose.
|
||||||
if (fm.current_phase_name !== undefined && fm.current_phase_name !== null) {
|
const fmPhaseName = fm.current_phase_name;
|
||||||
const canonicalName = String(fm.current_phase_name);
|
if (typeof fmPhaseName === 'string' || typeof fmPhaseName === 'number') {
|
||||||
|
const canonicalName = String(fmPhaseName);
|
||||||
const existing = stateExtractField(modified, 'Current Phase Name');
|
const existing = stateExtractField(modified, 'Current Phase Name');
|
||||||
if (existing !== null && existing !== canonicalName) {
|
if (existing !== null && existing !== canonicalName) {
|
||||||
const replaced = stateReplaceField(modified, 'Current Phase Name', canonicalName);
|
const replaced = stateReplaceField(modified, 'Current Phase Name', canonicalName);
|
||||||
@@ -1821,7 +1823,6 @@ function stripTemplatePlaceholders(
|
|||||||
const fieldName = m[1];
|
const fieldName = m[1];
|
||||||
const value = m[2];
|
const value = m[2];
|
||||||
if (TEMPLATE_PLACEHOLDER_VALUE.test(value)) {
|
if (TEMPLATE_PLACEHOLDER_VALUE.test(value)) {
|
||||||
const placeholder = value.trim();
|
|
||||||
const cleared = `**${fieldName}:** (pending)`;
|
const cleared = `**${fieldName}:** (pending)`;
|
||||||
replacements.push({ lineIdx: i, before: line, after: cleared, fieldName });
|
replacements.push({ lineIdx: i, before: line, after: cleared, fieldName });
|
||||||
}
|
}
|
||||||
@@ -1874,8 +1875,6 @@ function deduplicateSessionArchive(
|
|||||||
for (let i = sectionIdx + 1; i < hs.length; i++) {
|
for (let i = sectionIdx + 1; i < hs.length; i++) {
|
||||||
if (hs[i].level === 2) { sectionEnd = hs[i].offset; break; }
|
if (hs[i].level === 2) { sectionEnd = hs[i].offset; break; }
|
||||||
}
|
}
|
||||||
const sectionContent = content.slice(sectionStart, sectionEnd);
|
|
||||||
|
|
||||||
// Count `### Session — …` H3 sub-headings inside the section.
|
// Count `### Session — …` H3 sub-headings inside the section.
|
||||||
const archiveHeadings = hs.filter(
|
const archiveHeadings = hs.filter(
|
||||||
(h) => h.level === 3 && h.offset >= sectionStart && h.offset < sectionEnd && SESSION_ARCHIVE_H3.test(h.text),
|
(h) => h.level === 3 && h.offset >= sectionStart && h.offset < sectionEnd && SESSION_ARCHIVE_H3.test(h.text),
|
||||||
|
|||||||
@@ -367,8 +367,7 @@ describe('ADR-1817 §2: rebuild reconciles **By Phase:** table via phaseInventor
|
|||||||
{ number: '3', name: 'Test Phase', planCount: 5, summaryCount: 4 },
|
{ number: '3', name: 'Test Phase', planCount: 5, summaryCount: 4 },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const result = transitionCore(drifted, { kind: 'rebuild' }, baseDeps);
|
// First call with no phaseInventoryProvider → no-op (covered by its own test below).
|
||||||
// Note: passing baseDeps here (no provider) → reconcile is a no-op.
|
|
||||||
// Re-run with the provider-wired deps:
|
// Re-run with the provider-wired deps:
|
||||||
const result2 = transitionCore(drifted, { kind: 'rebuild' }, deps);
|
const result2 = transitionCore(drifted, { kind: 'rebuild' }, deps);
|
||||||
// Strip the audit log so we only inspect LIVE table rows (the log's
|
// Strip the audit log so we only inspect LIVE table rows (the log's
|
||||||
@@ -421,7 +420,6 @@ describe('ADR-1817 §2: rebuild reconciles **By Phase:** table via phaseInventor
|
|||||||
describe('ADR-1817 §5/§6: rebuild does not affect sync or prune (regression guard, criterion #7)', () => {
|
describe('ADR-1817 §5/§6: rebuild does not affect sync or prune (regression guard, criterion #7)', () => {
|
||||||
test('sync still patches its three frontmatter fields when rebuild is also available', () => {
|
test('sync still patches its three frontmatter fields when rebuild is also available', () => {
|
||||||
const state = cleanState();
|
const state = cleanState();
|
||||||
const before = state;
|
|
||||||
const result = transitionCore(
|
const result = transitionCore(
|
||||||
state,
|
state,
|
||||||
{ kind: 'sync', totalPlansInPhase: 7, percent: 50 },
|
{ kind: 'sync', totalPlansInPhase: 7, percent: 50 },
|
||||||
|
|||||||
Reference in New Issue
Block a user