From aaabe5949edea987f8f8497232f62545ca72bc55 Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Sat, 16 May 2026 03:37:10 -0400 Subject: [PATCH] fix: recognize legacy salvage manual review backlog --- scripts/operator-readiness-dashboard.js | 11 ++++- .../operator-readiness-dashboard.test.js | 45 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/scripts/operator-readiness-dashboard.js b/scripts/operator-readiness-dashboard.js index ba1e6555..d5b0915c 100644 --- a/scripts/operator-readiness-dashboard.js +++ b/scripts/operator-readiness-dashboard.js @@ -243,6 +243,14 @@ function includesAll(text, needles) { return needles.every(needle => text.includes(needle)); } +function hasLegacySalvageTracking({ stalePrSalvage, legacyInventory, roadmap }) { + return stalePrSalvage.includes('Manual review tail') + || stalePrSalvage.includes('Remaining Manual-Review Backlog') + || stalePrSalvage.includes('Translator/manual review') + || legacyInventory.includes('Translator/manual review') + || roadmap.includes('ITO-55'); +} + function runCommand(command, args, options = {}) { const result = spawnSync(command, args, { cwd: options.cwd, @@ -286,6 +294,7 @@ function buildRequirements(rootDir, platformReport) { const progressSync = readText(rootDir, 'docs/architecture/progress-sync-contract.md'); const observabilityReadiness = readText(rootDir, 'docs/architecture/observability-readiness.md'); const stalePrSalvage = readText(rootDir, 'docs/stale-pr-salvage-ledger.md'); + const legacyInventory = readText(rootDir, 'docs/legacy-artifact-inventory.md'); const supplyChainRunbook = readText(rootDir, 'docs/security/supply-chain-incident-response.md'); const supplyChainWorkflow = readText(rootDir, '.github/workflows/supply-chain-watch.yml'); const packageJson = readPackage(rootDir); @@ -412,7 +421,7 @@ function buildRequirements(rootDir, platformReport) { 'legacy-salvage', 'Audit, prune, or attach legacy work', 'docs/stale-pr-salvage-ledger.md and legacy inventory', - stalePrSalvage.includes('Manual review tail') || roadmap.includes('ITO-55') + hasLegacySalvageTracking({ stalePrSalvage, legacyInventory, roadmap }) ? 'in_progress' : 'not_complete', 'legacy salvage ledger and ITO-55 tracking are present', diff --git a/tests/scripts/operator-readiness-dashboard.test.js b/tests/scripts/operator-readiness-dashboard.test.js index 675f8e55..63e08341 100644 --- a/tests/scripts/operator-readiness-dashboard.test.js +++ b/tests/scripts/operator-readiness-dashboard.test.js @@ -190,6 +190,51 @@ function runTests() { } })) passed++; else failed++; + if (test('legacy salvage recognizes the real manual-review backlog heading', () => { + const rootDir = createTempDir('operator-dashboard-legacy-salvage-'); + + try { + seedRepo(rootDir, { + 'docs/ECC-2.0-GA-ROADMAP.md': [ + 'https://linear.app/itomarkets/project/ecc-platform-roadmap-52b328ee03e1', + 'Linear ITO-44 ITO-59', + 'AgentShield PR #90 #78-#90', + 'AgentShield Enterprise Iteration', + 'ECC-Tools PR #78', + 'hosted promotion', + 'announcementGate' + ].join('\n'), + 'docs/stale-pr-salvage-ledger.md': [ + '# Stale PR Salvage Ledger', + '', + '## Remaining Manual-Review Backlog', + '', + '- #1609 Persian README translation', + '- #1563 zh-TW README sync' + ].join('\n') + }); + + const report = buildReport({ + allowUntracked: [], + exitCode: false, + format: 'json', + generatedAt: '2026-05-15T00:00:00.000Z', + help: false, + repos: [], + root: rootDir, + skipGithub: true, + thresholds: { maxOpenPrs: 20, maxOpenIssues: 20, maxDirtyFiles: 0 }, + useEnvGithubToken: false, + writePath: null + }); + + const legacySalvage = report.requirements.find(item => item.id === 'legacy-salvage'); + assert.strictEqual(legacySalvage.status, 'in_progress'); + } finally { + cleanup(rootDir); + } + })) passed++; else failed++; + if (test('markdown output can be written as the dashboard artifact', () => { const rootDir = createTempDir('operator-dashboard-markdown-'); const outputPath = path.join(rootDir, 'artifacts', 'dashboard.md');