diff --git a/docs/ECC-2.0-GA-ROADMAP.md b/docs/ECC-2.0-GA-ROADMAP.md index 6e29b419..810551bd 100644 --- a/docs/ECC-2.0-GA-ROADMAP.md +++ b/docs/ECC-2.0-GA-ROADMAP.md @@ -30,6 +30,9 @@ As of 2026-05-12: - `docs/releases/2.0.0-rc.1/publication-readiness.md` gates GitHub release, npm dist-tag, Claude plugin, Codex plugin, OpenCode package, billing, and announcement publication on fresh evidence fields. +- `docs/legacy-artifact-inventory.md` records that no `_legacy-documents-*` + directories exist in the current checkout and classifies + `legacy-command-shims/` as an opt-in archive/no-action surface. - AgentShield PR #53 reduced two context-rule false positives and closed the remaining AgentShield issues. - ECC PR #1778 recovered the useful stale #1413 network/homelab architect-agent @@ -189,7 +192,5 @@ Acceptance: AgentShield repo. 2. Audit ECC Tools billing and check-run surfaces before any native GitHub payments announcement. -3. Inventory `_legacy-documents-*` and map useful artifacts to landed, - milestone-tracked, salvage, or archive states. -4. Build the stale-PR salvage ledger from closed cleanup batches, then port +3. Build the stale-PR salvage ledger from closed cleanup batches, then port useful pieces in small attributed maintainer PRs. diff --git a/docs/legacy-artifact-inventory.md b/docs/legacy-artifact-inventory.md new file mode 100644 index 00000000..435c23d2 --- /dev/null +++ b/docs/legacy-artifact-inventory.md @@ -0,0 +1,68 @@ +# Legacy Artifact Inventory + +This inventory keeps legacy and stale-work cleanup from becoming implicit. Each +artifact should be classified as landed, milestone-tracked, salvage branch, or +archive/no-action before release work treats the queue as clean. + +## Classification States + +| State | Meaning | +| --- | --- | +| Landed | Useful work has already been ported to current `main` and verified. | +| Milestone-tracked | Useful work remains, but belongs to a named roadmap milestone. | +| Salvage branch | Useful work should be ported through a fresh maintainer branch with attribution. | +| Translator/manual review | Content may be useful, but cannot be safely imported automatically. | +| Archive/no-action | Artifact is intentionally retained or skipped; no active port is planned. | + +## Current Repository Scan + +As of 2026-05-12, the tracked repo has no `_legacy-documents-*` directories. + +Fresh check: + +```sh +find . -type d -name '_legacy-documents-*' -print +``` + +Expected result: no output. + +The only tracked legacy directory currently found by filename scan is +`legacy-command-shims/`. + +## Inventory + +| Artifact | State | Evidence | Action | +| --- | --- | --- | --- | +| `_legacy-documents-*` directories | Archive/no-action | No matching directories exist in the tracked checkout as of 2026-05-12. | Re-run the scan before release. If any appear, add each directory to this table before publishing. | +| `legacy-command-shims/` | Archive/no-action | `legacy-command-shims/README.md` states these retired short-name shims are opt-in and no longer loaded by the default plugin command surface. | Keep as an explicit compatibility archive. Do not move these back into the default plugin surface without a migration decision. | +| Closed-stale PR salvage ledger | Landed | `~/.cluster-swarm/handoffs/ecc-stale-salvage-ledger-20260512-0210.md` records useful stale work recovered through maintainer PRs. | Continue using the ledger pattern for future stale closures. | +| #1687 zh-CN localization tail | Translator/manual review | Large safe subsets landed in #1746-#1752; remaining pieces require translator/manual review per salvage ledger. | Do not blindly cherry-pick. Split by docs, commands, agents, and skills if a translator review lane opens. | + +## Legacy Command Shim Contents + +The compatibility archive currently contains 12 retired command shims: + +| Shim | Preferred current direction | +| --- | --- | +| `agent-sort.md` | Use maintained command or skill routing where available. | +| `claw.md` | Use maintained `scripts/claw.js` / `npm run claw` surfaces. | +| `context-budget.md` | Use maintained token/context budgeting skills. | +| `devfleet.md` | Use maintained agent/harness orchestration docs and skills. | +| `docs.md` | Use current documentation and release checklist workflows. | +| `e2e.md` | Use maintained E2E testing skills and test scripts. | +| `eval.md` | Use eval-harness and verification-loop skills. | +| `orchestrate.md` | Use maintained orchestration status and worktree scripts. | +| `prompt-optimize.md` | Use prompt-optimizer skill. | +| `rules-distill.md` | Use current rules and skill extraction workflows. | +| `tdd.md` | Use tdd-workflow and language-specific testing skills. | +| `verify.md` | Use verification-loop and package-specific verification skills. | + +## Release Rule + +Before any GA or rc publication pass: + +1. Re-run the `_legacy-documents-*` scan. +2. Re-run the closed-stale salvage ledger check. +3. Confirm every newly discovered legacy artifact is represented in this file. +4. Port useful work through fresh maintainer PRs with source attribution. +5. Leave archive/no-action artifacts out of default install and plugin loading. diff --git a/tests/docs/legacy-artifact-inventory.test.js b/tests/docs/legacy-artifact-inventory.test.js new file mode 100644 index 00000000..ce706431 --- /dev/null +++ b/tests/docs/legacy-artifact-inventory.test.js @@ -0,0 +1,114 @@ +'use strict'; + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const repoRoot = path.resolve(__dirname, '..', '..'); +const legacyShimsDir = path.join(repoRoot, 'legacy-command-shims', 'commands'); + +let passed = 0; +let failed = 0; + +function test(name, fn) { + try { + fn(); + console.log(` ✓ ${name}`); + passed++; + } catch (error) { + console.log(` ✗ ${name}`); + console.log(` Error: ${error.message}`); + failed++; + } +} + +function read(relativePath) { + return fs.readFileSync(path.join(repoRoot, relativePath), 'utf8'); +} + +function findLegacyDocumentDirs(dir) { + const results = []; + + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name === 'node_modules' || entry.name === '.git') { + continue; + } + + const nextPath = path.join(dir, entry.name); + + if (!entry.isDirectory()) { + continue; + } + + if (entry.name.startsWith('_legacy-documents-')) { + results.push(path.relative(repoRoot, nextPath)); + } + + results.push(...findLegacyDocumentDirs(nextPath)); + } + + return results.sort(); +} + +console.log('\n=== Testing legacy artifact inventory ===\n'); + +test('legacy artifact inventory documents classification states', () => { + const source = read('docs/legacy-artifact-inventory.md'); + + for (const state of [ + 'Landed', + 'Milestone-tracked', + 'Salvage branch', + 'Translator/manual review', + 'Archive/no-action', + ]) { + assert.ok(source.includes(state), `Missing classification state ${state}`); + } +}); + +test('any _legacy-documents directories are explicitly inventoried', () => { + const source = read('docs/legacy-artifact-inventory.md'); + const dirs = findLegacyDocumentDirs(repoRoot); + + for (const dir of dirs) { + assert.ok(source.includes(dir), `Missing legacy artifact inventory row for ${dir}`); + } +}); + +test('legacy command shims remain classified as an opt-in archive', () => { + const source = read('docs/legacy-artifact-inventory.md'); + const readme = read('legacy-command-shims/README.md'); + + assert.ok(source.includes('legacy-command-shims/')); + assert.ok(source.includes('Archive/no-action')); + assert.ok(readme.includes('no longer loaded by the default plugin command surface')); + assert.ok(readme.includes('short-term migration compatibility')); +}); + +test('legacy command shim table tracks the current archive contents', () => { + const source = read('docs/legacy-artifact-inventory.md'); + const shims = fs.readdirSync(legacyShimsDir) + .filter(fileName => fileName.endsWith('.md')) + .sort(); + + assert.strictEqual(shims.length, 12); + + for (const shim of shims) { + assert.ok(source.includes(`\`${shim}\``), `Missing legacy shim ${shim}`); + } +}); + +test('stale salvage backlog records the remaining manual-review tail', () => { + const source = read('docs/legacy-artifact-inventory.md'); + + assert.ok(source.includes('#1687 zh-CN localization tail')); + assert.ok(source.includes('Translator/manual review')); + assert.ok(source.includes('#1746-#1752')); +}); + +if (failed > 0) { + console.log(`\nFailed: ${failed}`); + process.exit(1); +} + +console.log(`\nPassed: ${passed}`);