Refresh Linear progress readiness detection

This commit is contained in:
Affaan Mustafa
2026-05-17 15:13:42 -04:00
parent 5c135fb846
commit 355c4f12cf
2 changed files with 87 additions and 8 deletions

View File

@@ -389,6 +389,46 @@ function supplyChainLocalProtectionGap({ roadmap, scripts }) {
return 'Linear status synchronization remains ITO-57 follow-up after each significant merge batch'; return 'Linear status synchronization remains ITO-57 follow-up after each significant merge batch';
} }
function hasCurrentLinearProgressSync({ roadmap, progressSync }) {
return includesAll(roadmap, [
'Linear live sync is current',
'operator progress snapshot',
]) && includesAll(progressSync, [
'node scripts/work-items.js sync-github --repo <owner/repo>',
'node scripts/status.js --json',
'Linear remains the external status surface',
]);
}
function hasLinearProgressContract({ roadmap, progressSync }) {
return includesAll(roadmap, ['ITO-44', 'ITO-59', 'Linear'])
&& includesAll(progressSync, ['GitHub', 'Linear', 'handoff', 'repo roadmap']);
}
function linearProgressStatus(context) {
if (hasCurrentLinearProgressSync(context)) {
return 'current';
}
return hasLinearProgressContract(context) ? 'in_progress' : 'not_complete';
}
function linearProgressEvidence(context) {
if (hasCurrentLinearProgressSync(context)) {
return 'Linear live sync and project progress snapshot are current; progress-sync contract defines the file-backed work-items/status path';
}
return 'repo mirror and progress-sync contract are present';
}
function linearProgressGap(context) {
if (hasCurrentLinearProgressSync(context)) {
return 'repeat Linear/project status update and local work-items sync after each significant merge batch';
}
return 'recurring Linear status sync and productized realtime sync remain pending';
}
function runCommand(command, args, options = {}) { function runCommand(command, args, options = {}) {
const result = spawnSync(command, args, { const result = spawnSync(command, args, {
cwd: options.cwd, cwd: options.cwd,
@@ -568,11 +608,9 @@ function buildRequirements(rootDir, platformReport) {
'linear-roadmap-and-progress', 'linear-roadmap-and-progress',
'Keep Linear roadmap detailed and progress tracking synchronized', 'Keep Linear roadmap detailed and progress tracking synchronized',
'Linear project mirror plus progress-sync contract', 'Linear project mirror plus progress-sync contract',
includesAll(roadmap, ['ITO-44', 'ITO-59', 'Linear']) && includesAll(progressSync, ['GitHub', 'Linear', 'handoff', 'repo roadmap']) linearProgressStatus({ roadmap, progressSync }),
? 'in_progress' linearProgressEvidence({ roadmap, progressSync }),
: 'not_complete', linearProgressGap({ roadmap, progressSync })
'repo mirror and progress-sync contract are present',
'recurring Linear status sync and productized realtime sync remain pending'
), ),
buildRequirement( buildRequirement(
'observability-for-self-use', 'observability-for-self-use',
@@ -651,7 +689,7 @@ function buildReport(options) {
top_actions: topActions, top_actions: topActions,
next_work_order: [ next_work_order: [
'Regenerate this dashboard from the final release commit before publication evidence is recorded.', 'Regenerate this dashboard from the final release commit before publication evidence is recorded.',
'Continue ITO-57 with Linear status synchronization for the scheduled supply-chain watch advisory-source report.', 'Repeat ITO-57 Linear/project status sync after the next significant merge batch or advisory-source refresh.',
'Complete ECC Tools Marketplace purchase/webhook readback, then run preflight and the live announcement gate before publishing native-payments copy.', 'Complete ECC Tools Marketplace purchase/webhook readback, then run preflight and the live announcement gate before publishing native-payments copy.',
'Resume ITO-45, ITO-46, and ITO-56 only after the generated dashboard and final release gates are refreshed.', 'Resume ITO-45, ITO-46, and ITO-56 only after the generated dashboard and final release gates are refreshed.',
], ],

View File

@@ -57,7 +57,9 @@ function seedRepo(rootDir, overrides = {}) {
'production Marketplace readback state', 'production Marketplace readback state',
'eb69412', 'eb69412',
'announcementGate', 'announcementGate',
'ITO-55' 'ITO-55',
'Linear live sync is current for the May 17 merge batch',
'operator progress snapshot'
].join('\n'), ].join('\n'),
'docs/releases/2.0.0-rc.1/publication-readiness.md': 'Claude plugin Codex plugin', 'docs/releases/2.0.0-rc.1/publication-readiness.md': 'Claude plugin Codex plugin',
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md': 'Claude plugin Codex plugin npm package Publication Paths', 'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md': 'Claude plugin Codex plugin npm package Publication Paths',
@@ -97,7 +99,12 @@ function seedRepo(rootDir, overrides = {}) {
'#1565 pt-BR README sync', '#1565 pt-BR README sync',
'no automatic import remains release-blocking' 'no automatic import remains release-blocking'
].join('\n'), ].join('\n'),
'docs/architecture/progress-sync-contract.md': 'GitHub PRs/issues/discussions Linear project local handoff repo roadmap scripts/work-items.js', 'docs/architecture/progress-sync-contract.md': [
'GitHub PRs/issues/discussions Linear project local handoff repo roadmap scripts/work-items.js',
'node scripts/work-items.js sync-github --repo <owner/repo>',
'node scripts/status.js --json',
'Linear remains the external status surface'
].join('\n'),
'docs/architecture/observability-readiness.md': 'observability-readiness.js', 'docs/architecture/observability-readiness.md': 'observability-readiness.js',
'docs/security/supply-chain-incident-response.md': 'TanStack Mini Shai-Hulud node-ipc scan-supply-chain-iocs.js supply-chain-advisory-sources.js', 'docs/security/supply-chain-incident-response.md': 'TanStack Mini Shai-Hulud node-ipc scan-supply-chain-iocs.js supply-chain-advisory-sources.js',
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md': 'TanStack Mini Shai-Hulud Node IPC follow-up node-ipc IOC scan', 'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md': 'TanStack Mini Shai-Hulud Node IPC follow-up node-ipc IOC scan',
@@ -239,8 +246,42 @@ function runTests() {
&& item.evidence.includes('all localization tails are attached to Linear ITO-55') && item.evidence.includes('all localization tails are attached to Linear ITO-55')
&& item.gap === 'repeat legacy scan before release' && item.gap === 'repeat legacy scan before release'
))); )));
assert.ok(report.requirements.some(item => (
item.id === 'linear-roadmap-and-progress'
&& item.status === 'current'
&& item.evidence.includes('Linear live sync')
&& item.gap === 'repeat Linear/project status update and local work-items sync after each significant merge batch'
)));
assert.ok(report.top_actions.some(item => item.id === 'naming-and-plugin-publication')); assert.ok(report.top_actions.some(item => item.id === 'naming-and-plugin-publication'));
assert.ok(!report.top_actions.some(item => item.id === 'legacy-salvage')); assert.ok(!report.top_actions.some(item => item.id === 'legacy-salvage'));
assert.ok(!report.top_actions.some(item => item.id === 'linear-roadmap-and-progress'));
} finally {
cleanup(rootDir);
}
})) passed++; else failed++;
if (test('Linear progress stays in progress until live sync evidence is mirrored', () => {
const rootDir = createTempDir('operator-dashboard-linear-progress-');
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 Enterprise Iteration',
'ECC-Tools PR #78',
'hosted promotion',
'announcementGate',
'ITO-55'
].join('\n')
});
const report = buildSeededReport(rootDir);
const linearProgress = report.requirements.find(item => item.id === 'linear-roadmap-and-progress');
assert.strictEqual(linearProgress.status, 'in_progress');
assert.strictEqual(linearProgress.evidence, 'repo mirror and progress-sync contract are present');
assert.strictEqual(linearProgress.gap, 'recurring Linear status sync and productized realtime sync remain pending');
assert.ok(report.top_actions.some(item => item.id === 'linear-roadmap-and-progress'));
} finally { } finally {
cleanup(rootDir); cleanup(rootDir);
} }