- Update dbis_core, cross-chain-pmm-lps, explorer-monorepo, metamask-integration, pr-workspace/chains - Omit embedded publish git dirs and empty placeholders from index Made-with: Cursor
146 lines
5.5 KiB
JavaScript
146 lines
5.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
const repoRoot = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', '..');
|
|
const matrixPath = path.join(repoRoot, 'reports', 'status', 'contract_verification_publish_matrix.json');
|
|
const packStatusPath = path.join(repoRoot, 'reports', 'status', 'publication-pack-explorer-status.json');
|
|
const outJson = path.join(repoRoot, 'reports', 'status', 'publication-actionable-backlog.json');
|
|
const outMd = path.join(repoRoot, 'docs', '11-references', 'PUBLICATION_ACTIONABLE_BACKLOG.md');
|
|
|
|
const targetChainIds = new Set(['1', '10', '56', '137', '8453']);
|
|
const nonActionableAutomation = new Set(['inventory-only', 'reference-only']);
|
|
const autoSubmittableAutomation = new Set(['repo-supported', 'partial']);
|
|
|
|
function ensureDir(filePath) {
|
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
}
|
|
|
|
function loadJson(filePath) {
|
|
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
}
|
|
|
|
function byAddress(statusReport) {
|
|
const index = new Map();
|
|
for (const pack of statusReport.packs || []) {
|
|
for (const entry of pack.entries || []) {
|
|
index.set(`${entry.chainId}:${entry.address.toLowerCase()}`, entry);
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
function toRow(entry) {
|
|
return `| ${entry.chainId} | ${entry.chainName} | ${entry.label} | \`${entry.address}\` | ${entry.contractType} | ${entry.automation} | ${entry.explorerStatus} | ${entry.nextAction} |`;
|
|
}
|
|
|
|
const matrix = loadJson(matrixPath);
|
|
const packStatus = loadJson(packStatusPath);
|
|
const statusIndex = byAddress(packStatus);
|
|
|
|
const backlogEntries = matrix.entries
|
|
.filter((entry) => targetChainIds.has(entry.chainId))
|
|
.map((entry) => {
|
|
const status = statusIndex.get(`${entry.chainId}:${entry.address.toLowerCase()}`) || {};
|
|
const explorerStatus = status.explorerStatus || 'not-in-pack-status';
|
|
let nextAction = 'No automatic action';
|
|
if (nonActionableAutomation.has(entry.automation)) {
|
|
nextAction = 'Keep inventory/docs aligned; do not treat as repo-owned submission target';
|
|
} else if (autoSubmittableAutomation.has(entry.automation)) {
|
|
nextAction = 'Submit automatically with repo-owned verification flow';
|
|
} else if (entry.automation === 'manual-or-external') {
|
|
nextAction = 'Manual or external closure only; missing repo-supported source bundle or ownership proof';
|
|
}
|
|
return {
|
|
...entry,
|
|
explorerStatus,
|
|
explorerDetail: status.explorerDetail || null,
|
|
nextAction,
|
|
};
|
|
});
|
|
|
|
const autoSubmittable = backlogEntries.filter((entry) => autoSubmittableAutomation.has(entry.automation));
|
|
const manualOrExternal = backlogEntries.filter((entry) => entry.automation === 'manual-or-external');
|
|
const inventoryOnly = backlogEntries.filter((entry) => nonActionableAutomation.has(entry.automation));
|
|
|
|
const byChain = new Map();
|
|
for (const entry of backlogEntries) {
|
|
const current = byChain.get(entry.chainId) || {
|
|
chainId: entry.chainId,
|
|
chainName: entry.chainName,
|
|
total: 0,
|
|
autoSubmittable: 0,
|
|
manualOrExternal: 0,
|
|
inventoryOnly: 0,
|
|
};
|
|
current.total += 1;
|
|
if (autoSubmittableAutomation.has(entry.automation)) current.autoSubmittable += 1;
|
|
if (entry.automation === 'manual-or-external') current.manualOrExternal += 1;
|
|
if (nonActionableAutomation.has(entry.automation)) current.inventoryOnly += 1;
|
|
byChain.set(entry.chainId, current);
|
|
}
|
|
|
|
const summaryRows = [...byChain.values()]
|
|
.sort((a, b) => Number(a.chainId) - Number(b.chainId))
|
|
.map((chain) => `| ${chain.chainId} | ${chain.chainName} | ${chain.total} | ${chain.autoSubmittable} | ${chain.manualOrExternal} | ${chain.inventoryOnly} |`)
|
|
.join('\n');
|
|
|
|
const autoRows = autoSubmittable.length
|
|
? autoSubmittable.map(toRow).join('\n')
|
|
: '| - | - | - | - | - | - | - | Automatic submission backlog is currently empty for the requested packs |';
|
|
|
|
const manualRows = manualOrExternal.length
|
|
? manualOrExternal.map(toRow).join('\n')
|
|
: '| - | - | - | - | - | - | - | No manual-or-external backlog |';
|
|
|
|
const payload = {
|
|
generatedAt: new Date().toISOString(),
|
|
targetChains: [...targetChainIds],
|
|
summary: [...byChain.values()].sort((a, b) => Number(a.chainId) - Number(b.chainId)),
|
|
autoSubmittable,
|
|
manualOrExternal,
|
|
inventoryOnlyCount: inventoryOnly.length,
|
|
};
|
|
|
|
const md = `# Publication Actionable Backlog
|
|
|
|
**Generated:** ${payload.generatedAt}
|
|
|
|
This artifact separates the five requested publication packs into:
|
|
|
|
- addresses we can honestly treat as **auto-submittable** from the repo
|
|
- addresses that are **manual or external**
|
|
- addresses that are only **inventory/reference tracking**
|
|
|
|
## Chain Summary
|
|
|
|
| Chain ID | Chain | Total Entries | Auto-submittable | Manual / External | Inventory / Reference |
|
|
| --- | --- | ---: | ---: | ---: | ---: |
|
|
${summaryRows}
|
|
|
|
## Auto-submittable backlog
|
|
|
|
| Chain ID | Chain | Label | Address | Type | Automation | Explorer Status | Next Action |
|
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
${autoRows}
|
|
|
|
## Manual or external backlog
|
|
|
|
| Chain ID | Chain | Label | Address | Type | Automation | Explorer Status | Next Action |
|
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
${manualRows}
|
|
|
|
## Closure note
|
|
|
|
For the five requested packs, the repo-owned **automatic** submission pass is complete when the auto-submittable backlog is empty.
|
|
Any remaining rows in the manual/external table require source provenance, ownership confirmation, or a non-repo verification process before they can be closed honestly.
|
|
`;
|
|
|
|
ensureDir(outJson);
|
|
ensureDir(outMd);
|
|
fs.writeFileSync(outJson, JSON.stringify(payload, null, 2) + '\n');
|
|
fs.writeFileSync(outMd, md + '\n');
|
|
|
|
console.log(`Wrote:\n- ${outJson}\n- ${outMd}`);
|