From 9619662bcb42c748ef2d7d00a18a3054092b2084 Mon Sep 17 00:00:00 2001 From: Qwynn Marcelle Date: Wed, 22 Jul 2026 19:35:10 -0400 Subject: [PATCH 1/3] docs(audit): record 2026-07-22 worktree/Linear reconciliation audit + preservation Adds the read-only reconciliation audit artifacts and the preservation record for the feature/vr-639-640-spec-cli-prereqs working tree: - repository-reconciliation-report.md / .json / remediation-checklist.md - preservation/ (tracked-changes.patch, untracked-validator.ts, MANIFEST.md) Audit-only commit; contains no product implementation changes. --- .../2026-07-22/preservation/MANIFEST.md | 47 ++ .../preservation/tracked-changes.patch | 468 ++++++++++++++++++ .../preservation/untracked-validator.ts | 6 + .../2026-07-22/remediation-checklist.md | 125 +++++ .../repository-reconciliation-report.md | 180 +++++++ .../2026-07-22/repository-reconciliation.json | 187 +++++++ 6 files changed, 1013 insertions(+) create mode 100644 docs/audits/worktree-reconciliation/2026-07-22/preservation/MANIFEST.md create mode 100644 docs/audits/worktree-reconciliation/2026-07-22/preservation/tracked-changes.patch create mode 100644 docs/audits/worktree-reconciliation/2026-07-22/preservation/untracked-validator.ts create mode 100644 docs/audits/worktree-reconciliation/2026-07-22/remediation-checklist.md create mode 100644 docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation-report.md create mode 100644 docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation.json diff --git a/docs/audits/worktree-reconciliation/2026-07-22/preservation/MANIFEST.md b/docs/audits/worktree-reconciliation/2026-07-22/preservation/MANIFEST.md new file mode 100644 index 0000000..230105a --- /dev/null +++ b/docs/audits/worktree-reconciliation/2026-07-22/preservation/MANIFEST.md @@ -0,0 +1,47 @@ +# Preservation Manifest — `feature/vr-639-640-spec-cli-prereqs` working tree + +**Created:** 2026-07-22 · **Source checkout:** `/Users/user1/WebstormProjects/agents-audit` (branch `feature/vr-639-640-spec-cli-prereqs`, HEAD `b6c092b`) + +Purpose: capture the only known copy of the uncommitted reconciliation work **before** any integration action. Preservation was fully non-destructive — the source working tree was not switched, staged, reset, or cleaned. Three independent mechanisms preserve the same content. + +## At-risk content preserved +- **2 unique CLI integration tests** in `packages/agents-audit/src/cli.integration.test.ts` + (`--check` + `--dry-run` drift gate still fails; `--force` surfaces relocated invalid file). Confirmed present in the patch (2 matches). +- **`packages/spec/CHANGELOG.md`** [0.4.4] reconciliation narrative. +- **Untracked `packages/spec/src/validator.ts`** (byte-identical to `origin/main`). +- Full tracked delta: **15 files, +179 / −39**. + +## Mechanism 1 — Git tag (git-object snapshot of tracked changes) +- **Ref:** `preserve/vr-639-640-worktree-2026-07-22` +- **Commit:** `f5e3e0f16dd7c02a96eb2794aebd6e9789d07eb2` (created via `git stash create`, non-destructive) +- **Verification:** `git diff HEAD preserve/vr-639-640-worktree-2026-07-22 --stat` → `15 files changed, 179 insertions(+), 39 deletions(-)` — matches the live `git diff HEAD` exactly. +- **Recovery (from any checkout of this repo):** + ``` + git checkout -b recover/vr-639-640 b6c092b + git cherry-pick --no-commit preserve/vr-639-640-worktree-2026-07-22^..preserve/vr-639-640-worktree-2026-07-22 # or: + git restore --source=preserve/vr-639-640-worktree-2026-07-22 --worktree -- . + ``` + (Tag is currently local only; push with `git push origin preserve/vr-639-640-worktree-2026-07-22` to make it remote-durable.) + +## Mechanism 2 — Binary-safe patch (committed in-repo, remote-durable once the docs branch is pushed) +- **File:** `tracked-changes.patch` (`git diff HEAD --binary`) +- **SHA-256:** `77513874ea0f5de129ac385cdfa9cd4c2220e89ce684df33a9d1b5c32a449387` +- **Size:** 18747 bytes · **Scope:** tracked modifications only (no untracked files; none were staged). +- **Recovery:** + ``` + git checkout b6c092b # the base the patch was cut against + git apply docs/audits/worktree-reconciliation/2026-07-22/preservation/tracked-changes.patch + ``` + +## Mechanism 3 — Verbatim untracked file copy +- **File:** `untracked-validator.ts` (verbatim copy of the untracked `packages/spec/src/validator.ts`) +- **SHA-256:** `fb9a96121d18bbebeddb5ff3df574fd4ac0107cec225564ee4dd4b9c62d74570` +- **Note:** confirmed **identical** to `git show origin/main:packages/spec/src/validator.ts` — also recoverable from `origin/main`. + +## Exclusions +- `claudedocs/audit-aa-report.md` — pre-existing untracked prior-audit doc, unrelated to this reconciliation; intentionally not part of this preservation set (not at-risk reconciliation work). +- `docs/` audit artifacts — preserved via the audit-artifact commit (Phase 2), not this patch. +- No secrets, tokens, credentials, or environment values are present in any preserved artifact (verified by inspection; the tracked delta is spec/CLI source + CHANGELOG + lockfile). + +## Integrity statement +Source working tree after preservation: still dirty (18 status entries), HEAD still `b6c092b` — unchanged by the preservation operation. diff --git a/docs/audits/worktree-reconciliation/2026-07-22/preservation/tracked-changes.patch b/docs/audits/worktree-reconciliation/2026-07-22/preservation/tracked-changes.patch new file mode 100644 index 0000000..f4c2ada --- /dev/null +++ b/docs/audits/worktree-reconciliation/2026-07-22/preservation/tracked-changes.patch @@ -0,0 +1,468 @@ +diff --git a/packages/agents-audit/package.json b/packages/agents-audit/package.json +index 32d57dd..ab0f089 100644 +--- a/packages/agents-audit/package.json ++++ b/packages/agents-audit/package.json +@@ -66,7 +66,7 @@ + }, + "dependencies": { + "@workspacejson/rules": "workspace:*", +- "@workspacejson/spec": "0.4.1", ++ "@workspacejson/spec": "workspace:*", + "@inquirer/core": "^9.0.0", + "boxen": "^7.1.1", + "cli-table3": "^0.6.5", +diff --git a/packages/agents-audit/src/cli.integration.test.ts b/packages/agents-audit/src/cli.integration.test.ts +index 5487bae..ad78450 100644 +--- a/packages/agents-audit/src/cli.integration.test.ts ++++ b/packages/agents-audit/src/cli.integration.test.ts +@@ -111,6 +111,50 @@ describe('CLI integration', () => { + logSpy.mockRestore(); + }); + ++ it('still fails the drift gate when --check is combined with --dry-run', async () => { ++ const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); ++ const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); ++ mocks.generateWorkspaceJson.mockResolvedValueOnce({ ++ path: '/repo/.agents/workspace.json', ++ written: false, ++ skipped: false, ++ drift: true, ++ preservedManual: true, ++ content: { staged: true }, ++ }); ++ ++ const exitCode = await runCli(['node', 'agents-audit', 'generate', '/repo', '--check', '--dry-run']); ++ ++ expect(exitCode).toBe(1); ++ const errorCalls = (errorSpy as unknown as { mock: { calls: unknown[][] } }).mock.calls; ++ expect(errorCalls.flat().join(' ')).toContain('manual evidence is untouched'); ++ expect(logSpy).toHaveBeenCalledWith(JSON.stringify({ staged: true }, null, 2)); ++ errorSpy.mockRestore(); ++ logSpy.mockRestore(); ++ }); ++ ++ it('surfaces the relocated invalid file when --force recovers a fresh generate', async () => { ++ const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); ++ mocks.generateWorkspaceJson.mockResolvedValueOnce({ ++ path: '/repo/.agents/workspace.json', ++ written: true, ++ skipped: false, ++ drift: true, ++ preservedManual: false, ++ invalidFileMoved: '/repo/.agents/workspace.json.invalid.2026-01-01T00-00-00-000Z', ++ content: {}, ++ }); ++ ++ const exitCode = await runCli(['node', 'agents-audit', 'generate', '/repo', '--force']); ++ ++ expect(exitCode).toBe(0); ++ const logCalls = (logSpy as unknown as { mock: { calls: unknown[][] } }).mock.calls; ++ const logs = logCalls.flat().join(' '); ++ expect(logs).toContain('Generated /repo/.agents/workspace.json'); ++ expect(logs).toContain('/repo/.agents/workspace.json.invalid.2026-01-01T00-00-00-000Z'); ++ logSpy.mockRestore(); ++ }); ++ + it('treats --dir as an invalid option', async () => { + const exitCode = await runCli(['node', 'agents-audit', 'scan', '--dir', '/tmp/example']); + +diff --git a/packages/agents-audit/src/cli.ts b/packages/agents-audit/src/cli.ts +index 477e5de..f2d875d 100644 +--- a/packages/agents-audit/src/cli.ts ++++ b/packages/agents-audit/src/cli.ts +@@ -109,17 +109,24 @@ export async function runCli(argv: string[] = process.argv): Promise { + }); + spinner.stop(); + +- if (options.dryRun) { +- console.log(JSON.stringify(result.content, null, 2)); +- } else if (options.check) { ++ if (options.check) { + if (result.drift) { + console.error(`Generated sections are stale at ${result.path}; manual evidence is untouched. Run: agents-audit generate ${path}`); + exitCode = 1; + } else { + console.log(`Generated sections are current at ${result.path}`); + } ++ if (options.dryRun) { ++ console.log(JSON.stringify(result.content, null, 2)); ++ } ++ } else if (options.dryRun) { ++ console.log(JSON.stringify(result.content, null, 2)); + } else if (result.skipped) { + console.log(`Generated sections already current at ${result.path}; manual evidence preserved`); ++ } else if (result.invalidFileMoved) { ++ console.log(`Generated ${result.path}`); ++ console.log(pc.yellow(` Previous file was invalid and has been moved aside: ${result.invalidFileMoved}`)); ++ console.log(pc.yellow(' Manual evidence from the previous file was not recovered (it could not be parsed/validated).')); + } else { + console.log(`Generated ${result.path}`); + } +diff --git a/packages/agents-audit/src/package-metadata.test.ts b/packages/agents-audit/src/package-metadata.test.ts +index 104b4cb..bae8395 100644 +--- a/packages/agents-audit/src/package-metadata.test.ts ++++ b/packages/agents-audit/src/package-metadata.test.ts +@@ -12,7 +12,7 @@ describe('package metadata', () => { + it('keeps the spec package mature and discoverable', () => { + const pkg = readPackageJson('packages/spec/package.json'); + expect(pkg.name).toBe('@workspacejson/spec'); +- expect(pkg.version).toBe('0.4.2'); ++ expect(pkg.version).toBe('0.4.4'); + expect((pkg.repository as { directory?: string } | undefined)?.directory).toBe('packages/spec'); + expect((pkg.bin as { [key: string]: string } | undefined)?.['workspacejson-spec']).toBe('./dist/cli.js'); + expect((pkg.publishConfig as { access?: string } | undefined)?.access).toBe('public'); +diff --git a/packages/cli/package.json b/packages/cli/package.json +index abcd8aa..c471455 100644 +--- a/packages/cli/package.json ++++ b/packages/cli/package.json +@@ -43,7 +43,7 @@ + "typecheck": "tsc --noEmit" + }, + "dependencies": { +- "@workspacejson/spec": "0.4.1" ++ "@workspacejson/spec": "workspace:*" + }, + "devDependencies": { + "typescript": "^5.4.0", +diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts +index 4a78a05..15eb267 100644 +--- a/packages/cli/src/cli.ts ++++ b/packages/cli/src/cli.ts +@@ -1,6 +1,7 @@ + #!/usr/bin/env node + import { readFileSync } from "node:fs"; + import { dirname, resolve } from "node:path"; ++import { fileURLToPath } from "node:url"; + + import { extractModels, findDbtProjects, type DbtManifest } from "./dbt.js"; + import { computeProjectPrefix, canonical } from "./normalize.js"; +@@ -66,4 +67,6 @@ export function run(args: Args): number { + return result.total > 0 && result.matched === 0 ? 1 : 0; + } + +-process.exit(run(parseArgs(process.argv.slice(2)))); ++if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { ++ process.exit(run(parseArgs(process.argv.slice(2)))); ++} +diff --git a/packages/cli/src/join.ts b/packages/cli/src/join.ts +index 63a3169..412692b 100644 +--- a/packages/cli/src/join.ts ++++ b/packages/cli/src/join.ts +@@ -1,3 +1,5 @@ ++import type { FileIndexEntry } from "@workspacejson/spec"; ++ + import { normalizeModelPath } from "./normalize.js"; + + /** A dbt model as read from manifest.json. */ +@@ -9,10 +11,10 @@ export interface DbtModel { + + /** + * workspace.json behavioral intelligence, keyed by repository-root-relative +- * POSIX path (per @workspacejson/spec fileIndex, VR-640). Values are opaque +- * here — the join only needs key presence. ++ * POSIX path (per @workspacejson/spec fileIndex, VR-640). Values follow the ++ * spec's own FileIndexEntry contract — the join only needs key presence. + */ +-export type FileIndex = Record; ++export type FileIndex = Record; + + export interface JoinRow { + uniqueId: string; +diff --git a/packages/rules/package.json b/packages/rules/package.json +index f6738ad..15848f3 100644 +--- a/packages/rules/package.json ++++ b/packages/rules/package.json +@@ -61,7 +61,7 @@ + "typecheck": "tsc --noEmit" + }, + "dependencies": { +- "@workspacejson/spec": "0.4.1", ++ "@workspacejson/spec": "workspace:*", + "ajv": "^8.16.0", + "dedent": "^1.5.3", + "fast-glob": "^3.3.2", +diff --git a/packages/spec/CHANGELOG.md b/packages/spec/CHANGELOG.md +index 83efa7c..62787b2 100644 +--- a/packages/spec/CHANGELOG.md ++++ b/packages/spec/CHANGELOG.md +@@ -2,7 +2,45 @@ + + All notable changes to `@workspacejson/spec` are documented here. + +-## [0.4.2] - 2026-07-16 ++## [0.4.4] - Unreleased ++ ++Built on top of 0.4.3. Note: a branch-divergence incident meant 0.4.2/0.4.3 were ++published from `spike/v3d-ajv-validate` (the real AJV validator below) while this ++branch independently carried the VR-639/640 fixes below without that validator — ++neither branch alone was sufficient. This release reconciles both. See the incident ++ticket for the full account. ++ ++### Fixed ++- `coChange.files` documented and typed as an unordered pair (`string[]`, set semantics) ++ instead of a positional tuple (`[string, string]`) in `types.ts`. The schema already ++ constrained it to exactly two entries; `types.ts` was the split-brain source (VR-639). ++- `fileIndex` key format pinned to "repository-root-relative POSIX path (forward ++ slashes, no leading `./`, no drive letters)" in both schema mirrors, replacing the ++ unanchored "relative path" wording that caused a silent zero-row DataHub join (VR-640). ++ `fragility.file` carries the same anchor. ++- `@workspacejson/spec` dependency pin corrected from a fixed version string to ++ `workspace:*` in `agents-audit`, `rules`, and `cli`, so those packages build and test ++ against this package's own source rather than a stale published version. ++ ++### Added ++- `@workspacejson/cli` (`workspacejson-cli`): a dbt-manifest-to-workspace.json join ++ shim. Computes `projectPrefix = relative(gitRoot, dbtProjectDir)` and normalizes ++ `original_file_path` to the canonical `fileIndex` key format above. ++ ++## [0.4.3] - 2026-07-17 ++ ++### Fixed ++- The `agents-audit` CLI entry-point guard so it fires when invoked through npm's ++ `.bin` symlink (`npx agents-audit`, `npm exec agents-audit`). The guard previously ++ compared `resolve(process.argv[1])` against the resolved module URL, which never ++ matched through a symlink — every subcommand (`generate`, `scan`) silently no-op'd ++ and exited 0 instead of running. It now compares real paths via `realpathSync`. ++- Hardened `scripts/verify-package-tarball.mjs` for `agents-audit`: after packing and ++ installing the tarball fresh, it now runs `npx agents-audit generate` and asserts ++ `.agents/workspace.json` actually exists and parses, rather than trusting a clean ++ exit code. ++ ++## [0.4.2] - 2026-07-17 + + ### Added + - `workspacejson-spec validate ` command, exposed through `npx @workspacejson/spec`. +@@ -16,8 +54,8 @@ All notable changes to `@workspacejson/spec` are documented here. + - Packaged schema annotations now use the current Buildomator implementation name. + - `validateV4()` now follows the JSON Schema's v0.4 contract and requires only the v0.4 + `specVersion`; `coChange` and `fragility` remain optional schema fields. +-- Package repository and issue metadata now point to the canonical `workspace-json/agents-audit` +- repository and `packages/spec` directory. ++- Package tarball verification now requires the runtime schema and concrete fixed-group ++ dependency versions before publish. + + ## [0.4.1] - 2026-06-02 + +diff --git a/packages/spec/README.md b/packages/spec/README.md +index ea4d049..c77b862 100644 +--- a/packages/spec/README.md ++++ b/packages/spec/README.md +@@ -169,7 +169,11 @@ v0.3 documents remain valid — v0.4 is an additive extension. + } + ``` + +-Check `generated.specVersion === "0.4"` or use `validateV4(doc)` before accessing these fields. ++Check `generated.specVersion === "0.4"` or use `validateV4(doc)` to confirm the document ++is a valid v0.4 workspace.json before reading `generated`. Note that `coChange` and ++`fragility` are optional even on v0.4 documents — `validateV4(doc)` passing does not ++guarantee either array is present, so still guard with `Array.isArray(doc.generated.coChange)` ++before iterating. + + ## Migration from v0.1/v0.2 + +diff --git a/packages/spec/package.json b/packages/spec/package.json +index ba0fb74..cce0c99 100644 +--- a/packages/spec/package.json ++++ b/packages/spec/package.json +@@ -1,6 +1,6 @@ + { + "name": "@workspacejson/spec", +- "version": "0.4.2", ++ "version": "0.4.4", + "description": "JSON Schema and TypeScript types for workspace.json", + "license": "Apache-2.0", + "author": "workspace-json contributors", +@@ -61,6 +61,9 @@ + "test": "npm run build && vitest run", + "typecheck": "tsc --noEmit" + }, ++ "dependencies": { ++ "ajv": "^8.20.0" ++ }, + "devDependencies": { + "json-schema-to-typescript": "^14.0.0", + "typescript": "^5.4.0", +diff --git a/packages/spec/src/index.test.ts b/packages/spec/src/index.test.ts +index 2627b2a..92c3ac7 100644 +--- a/packages/spec/src/index.test.ts ++++ b/packages/spec/src/index.test.ts +@@ -3,6 +3,7 @@ import { dirname, resolve } from 'node:path'; + import { fileURLToPath } from 'node:url'; + import { describe, expect, it } from 'vitest'; + import { validate, validateLegacy, validateV4, version, workspaceJsonSchema } from './index.js'; ++import { compileSchemaValidator } from './validator.js'; + import type { CoChangeEntry } from './index.js'; + + const __dirname = dirname(fileURLToPath(import.meta.url)); +@@ -30,8 +31,22 @@ describe('@workspacejson/spec smoke test', () => { + }); + + describe('version', () => { +- it('is 0.4.2', () => { +- expect(version).toBe('0.4.2'); ++ it('is 0.4.4', () => { ++ expect(version).toBe('0.4.4'); ++ }); ++}); ++ ++describe('draft-2020-12 validator', () => { ++ it('enforces prefixItems, which draft-07 does not define', () => { ++ const validateTuple = compileSchemaValidator({ ++ $schema: 'https://json-schema.org/draft/2020-12/schema', ++ type: 'array', ++ prefixItems: [{ type: 'string' }], ++ items: {}, ++ }); ++ ++ expect(validateTuple([42])).toBe(false); ++ expect(validateTuple(['valid', 42])).toBe(true); + }); + }); + +@@ -56,6 +71,19 @@ describe('validate()', () => { + const bad = { ...minimalV3, generated: { ...minimalV3.generated, specVersion: '0.2' } }; + expect(validate(bad)).toBe(false); + }); ++ ++ it('rejects a shallowly plausible document that violates the packaged schema', () => { ++ const missingRequiredGenerator = { ++ ...minimalV3, ++ generated: { specVersion: '0.4', generatedAt: '2026-06-01T00:00:00Z' }, ++ }; ++ ++ expect(validate(missingRequiredGenerator)).toBe(false); ++ }); ++ ++ it('rejects additional root properties forbidden by the packaged schema', () => { ++ expect(validate({ ...minimalV3, unsupported: true })).toBe(false); ++ }); + }); + + describe('validateLegacy()', () => { +diff --git a/packages/spec/src/index.ts b/packages/spec/src/index.ts +index 4f6be0d..5d26fc6 100644 +--- a/packages/spec/src/index.ts ++++ b/packages/spec/src/index.ts +@@ -1,3 +1,8 @@ ++import { readFileSync } from 'node:fs'; ++import { fileURLToPath } from 'node:url'; ++ ++import { compileSchemaValidator } from './validator.js'; ++ + export { workspaceJsonSchema } from './schema.js'; + export type { + WorkspaceJson, +@@ -17,17 +22,21 @@ export type { + + import type { WorkspaceJsonV3, WorkspaceJsonV4 } from './types.js'; + +-export const version = '0.4.2'; ++type WorkspaceJsonDocument = WorkspaceJsonV3 | WorkspaceJsonV4; ++ ++// The runtime validator consumes the schema artifact that is published with ++// the package, rather than the authoring-time TypeScript mirror, so a build ++// that forgets to regenerate schema/v1.json fails validation instead of ++// silently drifting from it. ++const packagedSchema = JSON.parse( ++ readFileSync(fileURLToPath(new URL('../schema/v1.json', import.meta.url)), 'utf8'), ++) as object; ++const validateSchema = compileSchemaValidator(packagedSchema); ++ ++export const version = '0.4.4'; + + export function validate(data: unknown): data is WorkspaceJsonV3 | WorkspaceJsonV4 { +- if (typeof data !== 'object' || data === null) return false; +- const d = data as Record; +- if (!('manual' in d && 'generated' in d && 'agents' in d && 'health' in d)) return false; +- const gen = d['generated']; +- if (typeof gen !== 'object' || gen === null) return false; +- const g = gen as Record; +- return (g['specVersion'] === '0.3' || g['specVersion'] === '0.4') && +- typeof g['generatedAt'] === 'string'; ++ return validateSchema(data); + } + + export function validateV4(data: unknown): data is WorkspaceJsonV4 { +diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml +index 5ebe0e3..1959183 100644 +--- a/pnpm-lock.yaml ++++ b/pnpm-lock.yaml +@@ -34,8 +34,8 @@ importers: + specifier: workspace:* + version: link:../rules + '@workspacejson/spec': +- specifier: 0.4.1 +- version: 0.4.1 ++ specifier: workspace:* ++ version: link:../spec + boxen: + specifier: ^7.1.1 + version: 7.1.1 +@@ -71,8 +71,8 @@ importers: + packages/cli: + dependencies: + '@workspacejson/spec': +- specifier: 0.4.1 +- version: 0.4.1 ++ specifier: workspace:* ++ version: link:../spec + devDependencies: + tsup: + specifier: ^8.0.0 +@@ -87,8 +87,8 @@ importers: + packages/rules: + dependencies: + '@workspacejson/spec': +- specifier: 0.4.1 +- version: 0.4.1 ++ specifier: workspace:* ++ version: link:../spec + ajv: + specifier: ^8.16.0 + version: 8.20.0 +@@ -128,6 +128,10 @@ importers: + version: 1.6.1(@types/node@22.19.17) + + packages/spec: ++ dependencies: ++ ajv: ++ specifier: ^8.20.0 ++ version: 8.20.0 + devDependencies: + json-schema-to-typescript: + specifier: ^14.0.0 +@@ -757,10 +761,6 @@ packages: + '@vitest/utils@1.6.1': + resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==} + +- '@workspacejson/spec@0.4.1': +- resolution: {integrity: sha512-urLGyab4/KfY9xgSkYVhqv8eUmczSdOxn7Um0OGZT1+g9j+mGMjDClsB1bmQMCsisaunWnlkrA7SURS3odKlDg==} +- engines: {node: '>=20.0.0'} +- + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} +@@ -2484,8 +2484,6 @@ snapshots: + loupe: 2.3.7 + pretty-format: 29.7.0 + +- '@workspacejson/spec@0.4.1': {} +- + acorn-walk@8.3.5: + dependencies: + acorn: 8.16.0 +diff --git a/types/ambient.d.ts b/types/ambient.d.ts +index b241ee3..e0fca2d 100644 +--- a/types/ambient.d.ts ++++ b/types/ambient.d.ts +@@ -61,6 +61,10 @@ declare module 'node:module' { + export function createRequire(url: string | URL): (id: string) => unknown; + } + ++declare module 'node:url' { ++ export function fileURLToPath(url: string | URL): string; ++} ++ + declare module 'node:readline' { + export function emitKeypressEvents(stream: unknown): void; + } diff --git a/docs/audits/worktree-reconciliation/2026-07-22/preservation/untracked-validator.ts b/docs/audits/worktree-reconciliation/2026-07-22/preservation/untracked-validator.ts new file mode 100644 index 0000000..16812af --- /dev/null +++ b/docs/audits/worktree-reconciliation/2026-07-22/preservation/untracked-validator.ts @@ -0,0 +1,6 @@ +import Ajv2020 from 'ajv/dist/2020.js'; + +export function compileSchemaValidator(schema: object): (data: unknown) => data is T { + const ajv = new Ajv2020({ allErrors: true, strict: false, validateFormats: false }); + return ajv.compile(schema); +} diff --git a/docs/audits/worktree-reconciliation/2026-07-22/remediation-checklist.md b/docs/audits/worktree-reconciliation/2026-07-22/remediation-checklist.md new file mode 100644 index 0000000..0ad13a4 --- /dev/null +++ b/docs/audits/worktree-reconciliation/2026-07-22/remediation-checklist.md @@ -0,0 +1,125 @@ +# Remediation Checklist — `agents-audit` Worktree/Linear Reconciliation + +**Generated:** 2026-07-22 (audit pass) · **Status:** PROPOSED — do not execute until separate execution authorization is granted. + +Rules: work top-to-bottom. **Do not cross a `⛔ VERIFICATION PAUSE` until its checkpoint passes.** Every command below is what a *later* execution agent would run — this audit ran none of them. + +--- + +## Wave 0 — Preservation & Prerequisites *(do first; parallel-safe)* + +### 0.1 — Preserve the primary checkout's uncommitted tree 🔴 CRITICAL +- **Action:** snapshot the dirty working tree of `feature/vr-639-640-spec-cli-prereqs` without merging/pushing/discarding. +- **Evidence:** only copy of the 0.4.4 CHANGELOG split-brain narrative + 2 unique CLI tests + untracked `validator.ts`; a `reset --hard`/`checkout .`/`stash drop` destroys it. +- **Commands (later):** + ``` + git stash push -u -m "audit-2026-07-22 preservation: vr-639-640 reconciliation" && git stash apply # keep + restore + # OR, safer, a durable snapshot: + git branch preserve/vr-639-640-worktree-2026-07-22 + git add -A && git commit -m "wip: preserve reconciliation snapshot [no-merge]" # on the preserve branch + git format-patch -1 -o docs/audits/worktree-reconciliation/2026-07-22/ HEAD + git bundle create docs/audits/worktree-reconciliation/2026-07-22/vr-639-640-preserve.bundle preserve/vr-639-640-worktree-2026-07-22 + ``` +- **Expected:** snapshot commit + `.patch` + `.bundle` exist; original working tree restored intact. +- **Rollback:** `git stash pop` / delete the preserve branch — nothing else touched. +- **Linear after:** none. +- **Unlocks:** feature-branch teardown eligibility (Wave 4). + +### 0.2 — Archive-tag the superseded spike +- **Action:** tag `spike/v3d-ajv-validate` before it becomes a deletion candidate. +- **Evidence:** validator productionized into `main` via 0.4.2 (`6c1c01a`); scaffold-cli/pin duplicated in `release/0.4.4`. +- **Command (later):** `git tag archive/spike-v3d-ajv-validate spike/v3d-ajv-validate` +- **Checkpoint:** `git tag -l 'archive/*'` lists it. + +### 0.3 — Confirm `release/0.4.4` is the clean vehicle +- **Command (later):** `git -C /private/tmp/agents-audit-release-044 status --short` (expect empty) and `git rev-list --left-right --count origin/main...release/0.4.4` (expect `2 4`). +- **⛔ VERIFICATION PAUSE — G1:** human ratifies `release/0.4.4` as the 0.4.4 vehicle before any integration. + +--- + +## Wave 1 — Foundational Integration (`release/0.4.4` → `main`) + +### 1.1 — Refresh `release/0.4.4` from canonical +- **Action:** rebase/merge `origin/main` into `release/0.4.4` (behind 2 — pulls in the PR #17 readme work). +- **Expected conflicts:** low; likely `packages/spec/README.md`, `CHANGELOG.md`. +- **Command (later):** `git checkout release/0.4.4 && git rebase origin/main` (or merge). +- **Rollback:** `git rebase --abort`. + +### 1.2 — Port unique content from the preserved feature tree 🔴 CRITICAL +- **Action:** bring into `release/0.4.4`: + 1. the 2 `cli.integration.test.ts` cases (`--check` + `--dry-run` drift gate; `--force` relocated-invalid-file), and + 2. the 0.4.4 CHANGELOG split-brain narrative wording (reconcile with release/0.4.4's existing CHANGELOG). +- **Evidence:** `git diff release/0.4.4 -- packages/agents-audit/src/cli.integration.test.ts` (audit confirmed these are additions absent from release/0.4.4). +- **Expected:** `pnpm --filter agents-audit test` includes and passes the 2 new cases. +- **⛔ VERIFICATION PAUSE — G2/G4:** human confirms port scope and resolves the version-bump disagreement (spec-only vs all-packages → 0.4.4). + +### 1.3 — Open PR and pass CI +- **Command (later):** `gh pr create --base main --head release/0.4.4 --title "Release 0.4.4 — reconcile META-101/102 + @workspacejson/cli"`. +- **Validation:** CI green — `pnpm install && pnpm build && pnpm typecheck && pnpm test`. Anti-pattern gates: schema `$id` must be `https://www.workspacejson.dev/schema/v1.json`; CHANGELOG top entry must equal `package.json` version. +- **⛔ VERIFICATION PAUSE:** all required checks green before merge. Never push directly to `main`. + +### 1.4 — Merge PR +- **Expected:** `main` advances to 0.4.4; `origin/main:types.ts` now `files: string[]`; schema anchor present. +- **Rollback:** revert the merge PR. + +--- + +## Wave 2 — Dependent Integration + +### 2.1 — Merge docs PR #18 *(parallelizable with all of Wave 1)* +- **Evidence:** OPEN, MERGEABLE, base `main`, 1 commit `a91ec1d`. +- **Command (later):** `gh pr merge 18 --squash`. +- **Checkpoint:** PR #18 shows merged. + +### 2.2 — Publish 0.4.4 via Release workflow +- **Action:** trigger the fixed-group publish through CI (manual `npm publish` is fenced). +- **Evidence:** memory — Release workflow historically shows red on registry-propagation race but publishes land; do not trust the red alone, verify the registry. +- **⛔ VERIFICATION PAUSE:** confirm 0.4.4 actually on npm before touching Linear. + +--- + +## Wave 3 — Validation & Linear Reconciliation + +### 3.1 — Verify published 0.4.4 carries the fixes +- **Command (later):** install the published tarball; assert `types.ts`/schema anchor + `@workspacejson/cli` bin present. +- **Checkpoint:** both META-101 and META-102 fixes observable in the *published* artifact. + +### 3.2 — Update Linear (only after 3.1 passes) +- **META-101 / META-102:** post the comments drafted in `repository-reconciliation-report.md`; set status per **G3** (released vs keep-Done). +- **META-97:** comment linking this report. +- **CLI shim issue:** confirm the owning issue (vreko#491 / HAC-75) and close/annotate; create one if none exists. +- **⛔ VERIFICATION PAUSE — G3:** human decides status semantics before any status write. + +--- + +## Wave 4 — Cleanup *(only after Wave 3 verified)* + +### 4.1 — Prune dead worktree admin entries +- **Command (later):** `git worktree prune -v` (removes the 8 missing-dir entries; branches retained). + +### 4.2 — Delete integrated local branches (after archive tags) +- **Targets:** `fix/npm-access-command`, `fix/npm-publish-access`, `fix/npm-publisher-preflight`, `fix/npm-token-routing`, `fix/agents-audit-bin-entrypoint`, `fix/ci-pnpm-version`, `release/0.4.2`, `release/v0.3`, `codex-root-workspace-json`. +- **Precondition:** all confirmed `git cherry origin/main ` = 0 (done this audit) + optional `git tag archive/ `. +- **Command (later):** `git branch -d `. + +### 4.3 — Retire spike and feature branches +- **`spike/v3d-ajv-validate`:** after 0.4.4 merged + tag `archive/spike-v3d-ajv-validate` (0.2) → `git branch -D`. +- **`feature/vr-639-640-spec-cli-prereqs`:** **only** after 1.2 port confirmed and 0.1 snapshot exists → teardown. +- **⛔ VERIFICATION PAUSE — G5:** human authorizes each deletion. + +### 4.4 — Prune old dangling stashes +- **Targets:** 11 May-2026 dangling commits on merged history. Leave the 4 recent feature-branch ones until 0.1 snapshot is confirmed to cover them. + +--- + +## Local-main housekeeping (non-blocking, any time) +- Fast-forward stale local `main` (behind 21, no unique work): `git checkout main && git pull --ff-only`. + +--- + +## Global guardrails (apply to every step above) +- No direct pushes to `main`; PRs only. +- No manual `npm publish`; CI Release workflow only. +- No branch/worktree/stash deletion before its archive/preservation precondition. +- Re-verify, don't trust, the Release workflow's red status (known false-negative). +- Surface any new impl/spec divergence to the human (META-38); do not auto-resolve. diff --git a/docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation-report.md b/docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation-report.md new file mode 100644 index 0000000..5eb7fff --- /dev/null +++ b/docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation-report.md @@ -0,0 +1,180 @@ +# Repository & Linear Reconciliation Report — `agents-audit` + +**Audit date:** 2026-07-22 · **Mode:** read-only evidentiary audit · **State modified:** none (no commits, pushes, merges, branch/worktree/stash deletions, or Linear writes) + +> Governance note: this pass honors META-38 ("surface impl/spec divergence to the human; do NOT auto-resolve"). Where implementation and Linear disagree, the divergence is reported and a proposed action is drafted — nothing is resolved. + +--- + +## Executive Finding + +- **Worktrees:** 12 (`git worktree list`) — 3 live-on-disk + clean, 8 with a missing directory (prunable admin entries), 1 primary checkout that is **dirty**. +- **Branches with unique unmerged work:** 4 — `feature/vr-639-640-spec-cli-prereqs`, `release/0.4.4`, `spike/v3d-ajv-validate`, `docs/readme-clarity-final`. The other 10 local branches are patch-identical to `origin/main` (`git cherry` = 0). +- **Uncommitted work surfaces:** 1, and it is **the highest-risk item in the repo** — see below. +- **Relevant Linear issues:** META-101, META-102 (both Urgent/Done), META-97 (census anchor), META-31 (release pipeline), plus the orphan `@workspacejson/cli` shim. +- **Implementation/Linear discrepancies:** **2 material** — META-101 and META-102 are marked **Done** but their fixes are **absent from `origin/main` (the published 0.4.3 line)**. +- **Highest-risk potential loss:** the **uncommitted working tree** on the primary checkout (`feature/vr-639-640-spec-cli-prereqs`). It is the *only copy* of the 0.4.4 split-brain CHANGELOG narrative and 2 unique CLI integration tests. A `git checkout .`/`git stash drop`/`git reset --hard` destroys them. +- **Most important integration dependency:** `release/0.4.4` is the clean vehicle that carries the META-101/102 fixes + `@workspacejson/cli` + the real AJV validator, rebased on current `main` — but it has **no PR** and is **missing** the primary checkout's 2 unique tests + narrative. Those must be ported before the feature branch is torn down. +- **Is the repo safe to clean up now?** **No.** Cleanup must wait until (a) the uncommitted tree is preserved, (b) `release/0.4.4` is merged, and (c) META-101/102 are reconciled. + +--- + +## Repository Baseline + +| Item | Value | Basis | +|---|---|---| +| Remote (`origin`) | `https://github.com/workspace-json/agents-audit` | OBSERVED `git remote -v` | +| Canonical branch | **`main`** (`origin/HEAD → origin/main`) | OBSERVED `git remote show origin` | +| Canonical HEAD | `5a0e37e` (Merge PR #17) | OBSERVED | +| Canonical versions | spec `0.4.3`, agents-audit `0.4.3` | OBSERVED `git show origin/main:*/package.json` | +| Published npm | `0.4.3` | INFERRED (memory HAC-179 + origin/main; `npm view` blocked by local publish-fence hook) | +| PR-required workflow | Yes — all history landed via PR #1–#17 | OBSERVED merge commits | +| Protected branch | `main` | INFERRED (PR-only history) | +| Validation gates | `pnpm install`, `pnpm build`, `pnpm typecheck`, `pnpm test` | OBSERVED CLAUDE.md + `.github/workflows/ci.yml` | +| Linear | workspace `marcelle-labs`, team **Meta / Agent Infrastructure** | OBSERVED via Linear MCP | +| Working tree | **dirty** — 15 tracked modified, untracked `packages/spec/src/validator.ts` + `claudedocs/` | OBSERVED `git status` | + +> ID caveat (INFERRED): the repo branch prefix `vr-639-640` does **not** match Linear's `gitBranchName`. `VR-639`/`VR-640` resolve by content to **META-101 / META-102** (different git-branch slugs). Treat the `vr-*` names as informal. + +--- + +## Worktree and Branch Inventory + +| Surface | Path | Branch / Commit | Unique Work | Linear | Validation | Risk | Proposed Disposition | +|---|---|---|---|---|---|---|---| +| WT-primary | `…/WebstormProjects/agents-audit` | `feature/vr-639-640-spec-cli-prereqs` @ `b6c092b` **(dirty)** | Committed: superseded. **Uncommitted: unique** | META-101/102 | not run (read-only) | **HIGH** | `MANUAL_RECONCILIATION_REQUIRED` | +| WT-release-044 | `/private/tmp/agents-audit-release-044` | `release/0.4.4` @ `3a77e1b` (clean) | Yes — full 0.4.4 candidate | META-101/102 | CI n/a | MEDIUM | `MERGE_CANDIDATE` (open PR) | +| WT-v3d-ajv | `/private/tmp/agents-audit-v3d-ajv` *(dir missing)* | `spike/v3d-ajv-validate` @ `aee5f97` | Superseded by 0.4.2 + 0.4.4 | — | — | LOW | `SUPERSEDED` | +| WT-readme | `/private/tmp/agents-audit-readme-final` | `docs/readme-clarity-final` @ `a91ec1d` (clean) | 1 doc commit | — | PR #18 MERGEABLE | LOW | `MERGE_CANDIDATE` | +| WT-bin | `/private/tmp/agents-audit-bin-entrypoint` | `fix/agents-audit-bin-entrypoint` @ `161cffb` (clean) | None (PR #15 merged) | — | — | LOW | `ALREADY_INTEGRATED` | +| WT-release-042 | *(dir missing)* | `release/0.4.2` @ `316e00f` | None (PR #10 merged) | — | — | LOW | `ALREADY_INTEGRATED` | +| WT-npm-access | *(dir missing)* | `fix/npm-access-command` @ `e3e076d` | None (PR #13) | — | — | LOW | `ALREADY_INTEGRATED` | +| WT-npm-preflight | *(dir missing)* | `fix/npm-publish-access` @ `c3e69f3` | None (PR #11) | — | — | LOW | `ALREADY_INTEGRATED` | +| WT-npm-publisher | *(dir missing)* | `fix/npm-publisher-preflight` @ `cf8ff0e` | None (PR #14) | — | — | LOW | `ALREADY_INTEGRATED` | +| WT-npm-token | *(dir missing)* | `fix/npm-token-routing` @ `9f5af72` | None (PR #12) | — | — | LOW | `ALREADY_INTEGRATED` | +| WT-v3d-baseline | *(dir missing)* | detached @ `4ab426e` | None (reachable) | — | — | LOW | `ABANDON_CANDIDATE` | +| WT-hac-181 | *(dir missing)* | detached @ `8acc068` | None (= main base) | — | — | LOW | `ABANDON_CANDIDATE` | + +**Non-worktree local branches:** `codex-root-workspace-json` (cherry=0 → `ALREADY_INTEGRATED`), `fix/ci-pnpm-version` (PR #2), `release/v0.3` (PR #1), local `main` (stale, behind 21 → `REBASE_OR_REFRESH_CANDIDATE`, no unique work). **Remote-only:** `origin/fix/verify-published-registry-propagation-retry` (PR #16, integrated). + +**Stashes:** `git stash list` is **empty**. `git fsck --unreachable` surfaces 15 dangling stash-shaped commits — 4 recent ones anchored on the feature branch (2026-07-16→19) that may hold earlier snapshots of the current uncommitted work (`PRESERVE_PENDING_DECISION`), and 11 old May-2026 snapshots on already-merged history (`ABANDON_CANDIDATE`). + +--- + +## Linear Reconciliation Matrix + +| Linear Issue | Current Linear State | Observed Implementation State | Evidence | Proposed Update | +|---|---|---|---|---| +| **META-101** (VR-639) | **Done** / Urgent | `IMPLEMENTED_UNVERIFIED` — **not integrated** | `files: string[]` set-semantics present on feature/spike/release-0.4.4; `origin/main:types.ts:94` still `files: [string, string]`. | Comment: fix on branches only, not on published 0.4.3; ships with 0.4.4. **Hold status for human** (META-31). | +| **META-102** (VR-640) | **Done** / Urgent | `IMPLEMENTED_UNVERIFIED` — **not integrated** | Anchor "repository-root-relative POSIX" appears 2× in schema on feature/spike/release-0.4.4; **0×** on `origin/main`. | Same as META-101. | +| **META-97** | Backlog / High | `PARTIAL` | This audit is the census META-97 anchors (this pass also proposes dispositions, exceeding its inventory-only scope). | Comment linking this report; human decides fulfillment. | +| **META-31** | Backlog / High | `REFERENCE` | Root cause of "Done ≠ released" ambiguity behind META-101/102. | No change; cited as context. | +| `@workspacejson/cli` (no clear issue) | — | `ORPHAN_IMPLEMENTATION` | `packages/cli` on feature/spike/release-0.4.4; absent on `origin/main`. References vreko#491 / HAC-75 as CLI-scaffold home. | Confirm/create owning issue for the shim publish. | + +**Headline discrepancy:** two Urgent issues were closed **Done** on 2026-07-12 describing spec fixes "on branch `feature/vr-639-640-spec-cli-prereqs`" — but that branch was **never merged**, and `main` advanced to 0.4.3 through a *different* release line (0.4.2 → 0.4.3) that did **not** carry those fixes. The published spec still ships the exact tuple contradiction (META-101) and unanchored fileIndex (META-102) both issues declared fixed. This is a "Done-but-unshipped" gap, precisely the class META-31 exists to close. + +--- + +## Duplicate and Superseded Work + +Verified with `git patch-id --stable`: + +- **`scaffold @workspacejson/cli`** — **identical patch** `e1b4588` on `feature` (`4ab426e`), `spike` (`4ab426e`), and `release/0.4.4` (`8dca4e7`). Not on `main`. → one change, three carriers; `DUPLICATE_PATCH`. +- **`make workspace generation producer-conformant`** — `b6c092b` (feature, `725deb2`) **diverges** from `0be09a1` (merged via 0.4.2, `7fc421a`). Same message, different content → `IMPLEMENTATION_DIVERGED`. The 0.4.2 flavor is already in `main`. +- **`pin fileIndex key format`** — `aca3192` (feature/spike, `95075cb`) **diverges** from `0566ee9` (release/0.4.4, `751cdaa`). +- **`validate against packaged schema`** — spike `aee5f97` (`19bc1b2`) **superseded** by productionized `6c1c01a` ("ship strict packaged validator and CLI") merged to `main` via 0.4.2. The untracked `validator.ts` in the primary checkout is **byte-identical** to `origin/main`'s tracked copy. + +**Net:** `spike/v3d-ajv-validate` is fully superseded. `feature/vr-639-640`'s *committed* content is superseded by `release/0.4.4`; only its *uncommitted* delta is unique. + +--- + +## Conflict and Dependency Graph + +``` +origin/main (5a0e37e, 0.4.3) ──ships──► META-101/102 fixes ABSENT ⚠ discrepancy + │ + ├── release/0.4.4 (behind 2) ── refresh ──► carries META-101/102 + @workspacejson/cli + real validator + │ ▲ + │ │ MUST PORT (else lost): 2 unique CLI tests + 0.4.4 CHANGELOG narrative + │ │ + │ feature/vr-639-640 (dirty, stale 0.4.1 base) ── only copy of uncommitted delta + │ + ├── spike/v3d-ajv-validate ── SUPERSEDED (validator already in main via 0.4.2) + │ + └── docs/readme-clarity-final ── PR #18 (independent, parallelizable) +``` + +- **Must land first:** `release/0.4.4` (foundational — publishes the spec fixes + CLI). +- **Blocked-on-preservation:** feature branch teardown (holds only-copy content) and spike teardown (until 0.4.4 lands). +- **Parallel-safe:** docs PR #18; worktree-prune of the 8 missing-dir entries. +- **Do not merge:** `spike` and the raw `feature` committed history (both diverge/duplicate) — port selectively instead. +- **No secrets/credentials** were found in scope; the `fix/npm-*` branches touch CI token *routing config*, not secret values (all already merged). + +--- + +## Proposed Merge Sequence + +- **Wave 0 — Preservation & prerequisites** *(parallel)*: snapshot the primary checkout's uncommitted tree to a preservation branch + patch bundle + tag; archive-tag `spike/v3d-ajv-validate`; confirm `release/0.4.4` is clean and pushed. +- **Wave 1 — Foundational**: refresh `release/0.4.4` from `origin/main` (behind 2); **port** the 2 unique CLI tests + the 0.4.4 CHANGELOG split-brain narrative from the primary checkout into `release/0.4.4`; open PR → `main`; pass CI; merge. +- **Wave 2 — Dependent**: merge docs **PR #18**; publish **0.4.4** via the Release workflow (fixed-group bump — note the version inconsistency in G4). +- **Wave 3 — Validation & Linear**: verify published 0.4.4 carries META-101/102 fixes + `@workspacejson/cli`; update META-101/102 to reflect *released*; confirm/close the CLI shim issue; comment META-97 with this report. +- **Wave 4 — Cleanup**: `git worktree prune`; delete integrated local branches after archive tags; retire `spike` + `feature/vr-639-640` after preservation; prune old May dangling stashes. + +*Parallelizable:* Wave 0 tasks; docs PR #18 (any time); worktree-prune (any time — dirs already gone). + +--- + +## Proposed Linear Updates (paste-ready — NOT applied) + +**META-101 — comment (hold status for human):** +> Reconciliation audit 2026-07-22: the `coChange.files` set-semantics fix is present on `feature/vr-639-640-spec-cli-prereqs`, `spike/v3d-ajv-validate`, and `release/0.4.4`, but is **not** on `origin/main` — 0.4.3 still ships `files: [string, string]` in `types.ts:94`. This issue was closed Done on 2026-07-12 but never integrated to the canonical/published branch. It ships with `release/0.4.4` (currently unmerged, no PR). Recommend keeping Done only if "Done" means merged-to-branch; otherwise reopen until 0.4.4 publishes (see META-31). + +**META-102 — comment (hold status for human):** +> Reconciliation audit 2026-07-22: the `fileIndex` repo-root-relative POSIX anchor is present on `feature`/`spike`/`release/0.4.4` but absent from `origin/main` (0 matches for "repository-root-relative" in `schema/v1.json` at 0.4.3). Done 2026-07-12 but not integrated/published. Ships with `release/0.4.4`. + +**META-97 — comment (no status change):** +> Branch/worktree census delivered at `docs/audits/worktree-reconciliation/2026-07-22/`. 12 worktrees (3 live, 8 prunable, 1 primary-dirty); 14 local branches, 4 with unique unmerged work (`feature/vr-639-640`, `release/0.4.4`, `spike/v3d-ajv-validate`, `docs/readme-clarity-final`). Zero repo/Linear mutations in this pass. + +--- + +## Cleanup Candidates (deferred — nothing deleted) + +| Target | Safe only after | Later command | +|---|---|---| +| 8 prunable worktree admin entries | now (dirs already gone) | `git worktree prune -v` | +| `fix/npm-*`, `fix/agents-audit-bin-entrypoint`, `fix/ci-pnpm-version`, `release/0.4.2`, `release/v0.3`, `codex-root-workspace-json` | archive tag/bundle | `git branch -d ` | +| `spike/v3d-ajv-validate` | 0.4.4 merged + archive tag | `git branch -D spike/v3d-ajv-validate` | +| `feature/vr-639-640-spec-cli-prereqs` | **unique uncommitted content ported** + snapshot | teardown only after G2 | +| 11 old May dangling stashes | confirm superseded | `git gc` (implicit) | + +**No branch or worktree is proposed for deletion on age or name alone.** Each carries an explicit "safe only after" precondition. + +--- + +## Items Requiring Human Judgment + +1. **G1** — Ratify `release/0.4.4` (not `feature/vr-639-640`) as the blessed 0.4.4 vehicle. +2. **G2** — Confirm the 2 unique CLI tests + CHANGELOG narrative must be ported before feature-branch teardown. +3. **G3** — Decide META-101/102 status semantics (keep Done vs reopen-until-released). +4. **G4** — Confirm the fixed-group version bump: the feature working tree bumps **only** spec→0.4.4 (leaves agents-audit at 0.4.1), whereas `release/0.4.4` bumps **all** packages→0.4.4. These disagree. +5. **G5** — Authorize any branch/worktree deletion (none performed here). + +--- + +## Unknowns and Missing Evidence + +- Live npm versions — `npm view` blocked by the local architecture-fence hook; 0.4.3 is INFERRED. +- Byte-equality of local `release/0.4.4` vs `origin/release/0.4.4` (tracking shown, not diffed). +- Whether a dedicated Linear issue tracks the split-brain incident / 0.4.4 publish (memory calls it "HAC-199"; not located this pass — META-101's honest-correction section may be the only record). +- The owning issue for the `@workspacejson/cli` shim publish (references vreko#491 / HAC-75). +- Contents of the 4 recent feature-branch dangling stashes vs the current working tree (not diffed). + +--- + +## Final Recommendation + +**Proceed with remediation — but Wave 0 preservation first, and only under a separate execution authorization.** + +The single most important action is **non-destructive preservation of the primary checkout's uncommitted working tree** (the split-brain CHANGELOG narrative + 2 CLI tests) before anything else touches this repo — it is the only copy and the only genuinely at-risk work. Everything else (integrating `release/0.4.4`, reconciling META-101/102, cleaning prunable worktrees) is recoverable from committed history and can follow in sequence. + +**Safest first action:** on the primary checkout, create a preservation snapshot of the working tree (e.g. a dedicated preservation branch commit + `git bundle`/patch), *without* merging, pushing, or discarding — so the reconciliation delta survives independent of any later branch decision. diff --git a/docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation.json b/docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation.json new file mode 100644 index 0000000..a0a3b14 --- /dev/null +++ b/docs/audits/worktree-reconciliation/2026-07-22/repository-reconciliation.json @@ -0,0 +1,187 @@ +{ + "schemaVersion": "1.0", + "auditType": "worktree-linear-reconciliation", + "auditDate": "2026-07-22", + "readOnly": true, + "stateModified": false, + "repository": { + "name": "agents-audit", + "remote": "https://github.com/workspace-json/agents-audit", + "root": "/Users/user1/WebstormProjects/agents-audit", + "canonicalBranch": "origin/main", + "canonicalHead": "5a0e37e", + "canonicalHeadFull": "5a0e37e", + "canonicalVersions": { "spec": "0.4.3", "agents-audit": "0.4.3", "rules": "0.4.3" }, + "publishedNpmVersion": "0.4.3 (INFERRED from memory HAC-179 + origin/main; `npm view` blocked by local publish hook, not re-verified)", + "requiresPullRequests": true, + "protectedBranches": ["main"], + "validationCommands": ["pnpm install", "pnpm build", "pnpm typecheck", "pnpm test"], + "ciWorkflows": [".github/workflows/ci.yml", ".github/workflows/release.yml"], + "linear": { + "workspace": "marcelle-labs", + "team": "Meta / Agent Infrastructure", + "teamId": "e0428892-022d-4662-abf4-1a58bf4bfd6d", + "note": "Repo branch prefix 'vr-639-640' does NOT match Linear gitBranchName; VR-639/VR-640 resolve to META-101/META-102 by content." + } + }, + "worktrees": [ + { "id": "WT-primary", "path": "/Users/user1/WebstormProjects/agents-audit", "branch": "feature/vr-639-640-spec-cli-prereqs", "head": "b6c092b", "dirExists": true, "clean": false, "prunable": false, "note": "Primary checkout. Dirty tree = the only copy of the 0.4.4 reconciliation (CHANGELOG split-brain narrative + validator wiring + 2 unique CLI tests).", "disposition": "MANUAL_RECONCILIATION_REQUIRED" }, + { "id": "WT-bin", "path": "/private/tmp/agents-audit-bin-entrypoint", "branch": "fix/agents-audit-bin-entrypoint", "head": "161cffb", "dirExists": true, "clean": true, "prunable": false, "disposition": "ALREADY_INTEGRATED" }, + { "id": "WT-npm-access", "path": "/private/tmp/agents-audit-npm-access-command", "branch": "fix/npm-access-command", "head": "e3e076d", "dirExists": false, "clean": null, "prunable": true, "disposition": "ALREADY_INTEGRATED" }, + { "id": "WT-npm-preflight", "path": "/private/tmp/agents-audit-npm-preflight", "branch": "fix/npm-publish-access", "head": "c3e69f3", "dirExists": false, "clean": null, "prunable": true, "disposition": "ALREADY_INTEGRATED" }, + { "id": "WT-npm-publisher-preflight", "path": "/private/tmp/agents-audit-npm-publisher-preflight", "branch": "fix/npm-publisher-preflight", "head": "cf8ff0e", "dirExists": false, "clean": null, "prunable": true, "disposition": "ALREADY_INTEGRATED" }, + { "id": "WT-npm-token", "path": "/private/tmp/agents-audit-npm-token-routing", "branch": "fix/npm-token-routing", "head": "9f5af72", "dirExists": false, "clean": null, "prunable": true, "disposition": "ALREADY_INTEGRATED" }, + { "id": "WT-readme", "path": "/private/tmp/agents-audit-readme-final", "branch": "docs/readme-clarity-final", "head": "a91ec1d", "dirExists": true, "clean": true, "prunable": false, "disposition": "MERGE_CANDIDATE", "openPr": 18 }, + { "id": "WT-release-042", "path": "/private/tmp/agents-audit-release-042", "branch": "release/0.4.2", "head": "316e00f", "dirExists": false, "clean": null, "prunable": true, "disposition": "ALREADY_INTEGRATED" }, + { "id": "WT-release-044", "path": "/private/tmp/agents-audit-release-044", "branch": "release/0.4.4", "head": "3a77e1b", "dirExists": true, "clean": true, "prunable": false, "disposition": "MERGE_CANDIDATE" }, + { "id": "WT-v3d-ajv", "path": "/private/tmp/agents-audit-v3d-ajv", "branch": "spike/v3d-ajv-validate", "head": "aee5f97", "dirExists": false, "clean": null, "prunable": true, "disposition": "SUPERSEDED" }, + { "id": "WT-v3d-baseline", "path": "/private/tmp/agents-audit-v3d-baseline", "branch": null, "head": "4ab426e", "detached": true, "dirExists": false, "clean": null, "prunable": true, "disposition": "ABANDON_CANDIDATE", "note": "Detached at 4ab426e (scaffold-cli), reachable from feature/spike/release-0.4.4." }, + { "id": "WT-hac-181", "path": "/private/tmp/hac-181-prechange", "branch": null, "head": "8acc068", "detached": true, "dirExists": false, "clean": null, "prunable": true, "disposition": "ABANDON_CANDIDATE", "note": "Detached at 8acc068 (=local main / 0.4.1 base), reachable from main." } + ], + "branches": [ + { "name": "feature/vr-639-640-spec-cli-prereqs", "head": "b6c092b", "upstream": "none (no origin twin)", "ahead": 4, "behind": 21, "mergeBase": "8acc068", "cherryUnmerged": 4, "lastCommit": "2026-07-16", "uniqueCommits": ["b6c092b", "00bf8a1", "4ab426e", "aca3192"], "linear": ["META-101", "META-102"], "pr": null, "disposition": "MANUAL_RECONCILIATION_REQUIRED", "riskOfLoss": "HIGH", "note": "Based on stale 0.4.1. Committed work largely superseded by release/0.4.4. Value lives in the UNCOMMITTED working tree." }, + { "name": "release/0.4.4", "head": "3a77e1b", "upstream": "origin/release/0.4.4", "ahead": 4, "behind": 2, "mergeBase": "039773e", "cherryUnmerged": 4, "lastCommit": "2026-07-19", "uniqueCommits": ["3a77e1b", "5ded233", "8dca4e7", "0566ee9"], "linear": ["META-101", "META-102"], "pr": null, "disposition": "MERGE_CANDIDATE", "riskOfLoss": "MEDIUM", "note": "Clean 0.4.4 candidate rebased on current main. The recommended integration vehicle for META-101/102 + @workspacejson/cli + real validator. No PR opened yet." }, + { "name": "spike/v3d-ajv-validate", "head": "aee5f97", "upstream": "origin/spike/v3d-ajv-validate", "ahead": 3, "behind": 21, "mergeBase": "8acc068", "cherryUnmerged": 3, "lastCommit": "2026-07-16", "uniqueCommits": ["aee5f97", "4ab426e", "aca3192"], "linear": [], "pr": null, "disposition": "SUPERSEDED", "riskOfLoss": "LOW", "note": "AJV validator (aee5f97) was productionized into main via release/0.4.2 (6c1c01a). scaffold-cli/pin-fileIndex duplicated in release/0.4.4." }, + { "name": "docs/readme-clarity-final", "head": "a91ec1d", "upstream": "origin/docs/readme-clarity-final", "ahead": 1, "behind": 1, "mergeBase": "8e19086", "cherryUnmerged": 1, "lastCommit": "2026-07-22", "uniqueCommits": ["a91ec1d"], "linear": [], "pr": 18, "disposition": "MERGE_CANDIDATE", "riskOfLoss": "LOW", "note": "Open PR #18, MERGEABLE. Follow-up commit on same branch as merged PR #17." }, + { "name": "codex-root-workspace-json", "head": "5e35adc", "upstream": "origin/codex-root-workspace-json", "ahead": 1, "behind": 54, "mergeBase": "019257a", "cherryUnmerged": 0, "lastCommit": "2026-05-08", "linear": [], "pr": null, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW", "note": "cherry=0: its single commit is patch-present in main." }, + { "name": "fix/ci-pnpm-version", "head": "358b72a", "upstream": "origin/main", "ahead": 0, "behind": 37, "cherryUnmerged": 0, "lastCommit": "2026-05-13", "pr": 2, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "fix/agents-audit-bin-entrypoint", "head": "161cffb", "ahead": 0, "behind": 5, "cherryUnmerged": 0, "pr": 15, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "fix/npm-access-command", "head": "e3e076d", "ahead": 0, "behind": 9, "cherryUnmerged": 0, "pr": 13, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "fix/npm-publish-access", "head": "c3e69f3", "ahead": 0, "behind": 13, "cherryUnmerged": 0, "pr": 11, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "fix/npm-publisher-preflight", "head": "cf8ff0e", "ahead": 0, "behind": 7, "cherryUnmerged": 0, "pr": 14, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "fix/npm-token-routing", "head": "9f5af72", "ahead": 0, "behind": 11, "cherryUnmerged": 0, "pr": 12, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "release/0.4.2", "head": "316e00f", "ahead": 0, "behind": 15, "cherryUnmerged": 0, "pr": 10, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "release/v0.3", "head": "ef5814f", "ahead": 1, "behind": 39, "mergeBase": "1ea94ee", "cherryUnmerged": 0, "pr": 1, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" }, + { "name": "main (local)", "head": "8acc068", "upstream": "origin/main", "ahead": 0, "behind": 21, "cherryUnmerged": 0, "lastCommit": "2026-06-02", "disposition": "REBASE_OR_REFRESH_CANDIDATE", "riskOfLoss": "NONE", "note": "Stale local tracking branch (0.4.1). Fast-forward to origin/main. No unique work." }, + { "name": "origin/fix/verify-published-registry-propagation-retry", "head": "4738067", "remoteOnly": true, "pr": 16, "disposition": "ALREADY_INTEGRATED", "riskOfLoss": "LOW" } + ], + "stashes": { "count": 0, "note": "git stash list empty. However, dangling stash-shaped commits exist unreachable (see danglingCommits)." }, + "danglingCommits": [ + { "commit": "2e415d9", "date": "2026-07-17", "subject": "index on feature/vr-639-640-spec-cli-prereqs: b6c092b", "disposition": "PRESERVE_PENDING_DECISION", "note": "Dropped-stash index snapshot; likely superseded by current working tree." }, + { "commit": "774312d", "date": "2026-07-19", "subject": "WIP on feature/vr-639-640-spec-cli-prereqs: b6c092b", "disposition": "PRESERVE_PENDING_DECISION" }, + { "commit": "bce546f", "date": "2026-07-19", "subject": "index on feature/vr-639-640-spec-cli-prereqs: b6c092b", "disposition": "PRESERVE_PENDING_DECISION" }, + { "commit": "c300586", "date": "2026-07-16", "subject": "WIP on feature/vr-639-640-spec-cli-prereqs: 00bf8a1", "disposition": "PRESERVE_PENDING_DECISION" }, + { "commit": "(11 more, May 2026, on main/gsd-reviewfix)", "disposition": "ABANDON_CANDIDATE", "note": "Old dropped stashes, all on already-merged May history." } + ], + "uncommittedChanges": { + "surface": "WT-primary working tree (feature/vr-639-640-spec-cli-prereqs)", + "trackedModified": 15, + "untracked": ["packages/spec/src/validator.ts", "claudedocs/"], + "onlyCopy": true, + "riskOfLoss": "HIGH", + "uniqueContentNotInRelease_044": [ + "packages/spec/CHANGELOG.md — [0.4.4] split-brain incident narrative (documents VR-639/VR-640 + 0.4.2/0.4.3 divergence)", + "packages/agents-audit/src/cli.integration.test.ts — 2 tests: (a) --check + --dry-run drift gate still fails; (b) --force surfaces relocated invalid file" + ], + "supersededByRelease_044": [ + "packages/spec/src/index.ts validator wiring (release/0.4.4 has a cleaner variant + extra schema annotation)", + "packages/spec/src/types.ts set semantics (identical in both)", + "packages/spec/src/validator.ts (byte-identical to origin/main + release/0.4.4)", + "packages/cli scaffold (patch-identical 4ab426e == 8dca4e7)" + ], + "note": "Untracked validator.ts is byte-identical to origin/main's tracked copy; the feature branch simply never had it committed on its stale base." + }, + "pullRequests": [ + { "number": 18, "state": "OPEN", "head": "docs/readme-clarity-final", "base": "main", "mergeable": "MERGEABLE", "disposition": "MERGE_CANDIDATE" }, + { "number": 17, "state": "MERGED", "head": "docs/readme-clarity-final", "base": "main" }, + { "number": 16, "state": "MERGED", "head": "fix/verify-published-registry-propagation-retry" }, + { "number": 15, "state": "MERGED", "head": "fix/agents-audit-bin-entrypoint" }, + { "number": 14, "state": "MERGED", "head": "fix/npm-publisher-preflight" }, + { "number": 13, "state": "MERGED", "head": "fix/npm-access-command" }, + { "number": 12, "state": "MERGED", "head": "fix/npm-token-routing" }, + { "number": 11, "state": "MERGED", "head": "fix/npm-publish-access" }, + { "number": 10, "state": "MERGED", "head": "release/0.4.2" }, + { "number": 2, "state": "MERGED", "head": "fix/ci-pnpm-version" }, + { "number": 1, "state": "MERGED", "head": "release/v0.3" } + ], + "linearMappings": [ + { + "issue": "META-101", "alias": "VR-639", "title": "coChange.files tuple vs set — reconcile before CLI", + "linearState": "Done", "priority": "Urgent", + "observedImplementationState": "IMPLEMENTED_UNVERIFIED_NOT_INTEGRATED", + "evidence": "Set semantics (files: string[] + doc invariant) present on feature/vr-639-640, spike, release/0.4.4. ABSENT on origin/main (0.4.3) — `git show origin/main:packages/spec/src/types.ts` line 94 still `files: [string, string]`.", + "linearAccuracy": "OVERSTATES — Done but the fix is not on the canonical/published branch.", + "proposedUpdate": "Add comment (do NOT change status without human): 'Fix implemented on branch but not merged to main; origin/main 0.4.3 still ships the tuple. Ships with release/0.4.4.' Decide Done-semantics per META-31.", + "humanGate": true + }, + { + "issue": "META-102", "alias": "VR-640", "title": "fileIndex key format — pin to repo-root-relative POSIX", + "linearState": "Done", "priority": "Urgent", + "observedImplementationState": "IMPLEMENTED_UNVERIFIED_NOT_INTEGRATED", + "evidence": "Anchor string present (2x) in schema/v1.json on feature/spike/release-0.4.4. ABSENT on origin/main (0 matches for 'repository-root-relative').", + "linearAccuracy": "OVERSTATES — Done but not on canonical/published branch.", + "proposedUpdate": "Same as META-101. Ships with release/0.4.4.", + "humanGate": true + }, + { + "issue": "META-97", "title": "Branch/worktree census — inventory only, zero dispositions", + "linearState": "Backlog", "priority": "High", + "observedImplementationState": "PARTIAL", + "evidence": "This audit is the census META-97 anchors (though this pass also proposes dispositions, exceeding META-97's inventory-only scope).", + "proposedUpdate": "Comment linking docs/audits/worktree-reconciliation/2026-07-22/. Human decides whether this satisfies META-97 or feeds it.", + "humanGate": true + }, + { + "issue": "META-31", "title": "Linear Releases pipeline — Merged-on-merge, Done-on-release", + "linearState": "Backlog", "priority": "High", + "observedImplementationState": "REFERENCE", + "evidence": "Root cause of the META-101/102 'Done but unshipped' ambiguity. Until this lands, 'Done' does not mean released.", + "proposedUpdate": "No change. Cited as context.", + "humanGate": false + }, + { + "issue": "(none) @workspacejson/cli", "title": "dbt→workspace.json path-normalization shim", + "linearState": "no matching issue found in repo scan (references vreko#491 / HAC-75 as downstream CLI-scaffold home)", + "observedImplementationState": "ORPHAN_IMPLEMENTATION / IMPLEMENTED_UNVERIFIED", + "evidence": "packages/cli exists on feature/spike/release-0.4.4; ABSENT on origin/main. Ships with release/0.4.4.", + "proposedUpdate": "Confirm the owning CLI-scaffold issue (HAC-75/vreko#491). If none tracks the shim publish, create one.", + "humanGate": true + } + ], + "duplicatePatchRelationships": [ + { "kind": "IDENTICAL_PATCH", "patchId": "e1b4588", "commits": ["4ab426e (feature)", "8dca4e7 (release/0.4.4)", "4ab426e (spike)"], "subject": "scaffold @workspacejson/cli", "integrated": false }, + { "kind": "DIVERGED_SAME_MESSAGE", "commits": ["b6c092b (feature, pid 725deb2)", "0be09a1 (release/0.4.2 → MERGED to main, pid 7fc421a)"], "subject": "make workspace generation producer-conformant", "note": "Feature-branch flavor differs from the flavor merged via 0.4.2." }, + { "kind": "DIVERGED_SAME_MESSAGE", "commits": ["aca3192 (feature/spike, pid 95075cb)", "0566ee9 (release/0.4.4, pid 751cdaa)"], "subject": "pin fileIndex key format" }, + { "kind": "DIVERGED_SAME_MESSAGE", "commits": ["aee5f97 (spike, pid 19bc1b2)", "ff02337 (release/0.4.2 → MERGED, pid 4252a38)"], "subject": "validate against packaged schema", "note": "Spike superseded by productionized 6c1c01a on main." } + ], + "dependencies": [ + { "from": "release/0.4.4", "requires": "origin/main refresh (behind 2)", "type": "rebase-before-merge" }, + { "from": "release/0.4.4", "requires": "port 2 unique CLI tests + CHANGELOG narrative from WT-primary working tree", "type": "content-preservation", "critical": true }, + { "from": "META-101/102 status finalization", "requires": "release/0.4.4 merged + published", "type": "linear-after-integration" }, + { "from": "feature/vr-639-640 teardown", "requires": "unique working-tree content ported into release/0.4.4 line", "type": "preservation-before-cleanup", "critical": true }, + { "from": "spike/v3d-ajv-validate teardown", "requires": "release/0.4.4 merged", "type": "preservation-before-cleanup" } + ], + "proposedMergeOrder": [ + { "wave": 0, "title": "Preservation & prerequisites", "tasks": ["Snapshot WT-primary uncommitted tree to a preservation branch/patch/tag", "Archive-tag spike/v3d-ajv-validate", "Confirm release/0.4.4 clean & pushed"], "parallelizable": true }, + { "wave": 1, "title": "Foundational integration", "tasks": ["Refresh release/0.4.4 from origin/main", "Port WT-primary's 2 unique CLI tests + CHANGELOG narrative into release/0.4.4", "Open PR release/0.4.4 → main", "Pass CI (build/typecheck/test)", "Merge"] }, + { "wave": 2, "title": "Dependent integration", "tasks": ["Merge docs PR #18", "Publish 0.4.4 via Release workflow (fixed-group)"] }, + { "wave": 3, "title": "Validation & Linear reconciliation", "tasks": ["Verify published 0.4.4 carries META-101/102 fixes + @workspacejson/cli", "Update META-101/102 to released", "Confirm/close CLI shim issue", "Comment META-97 with this report"] }, + { "wave": 4, "title": "Cleanup", "tasks": ["git worktree prune", "Delete integrated local branches after archive tags", "Retire spike + feature/vr-639-640 after preservation", "Prune old May dangling stashes"] } + ], + "proposedLinearUpdates": [ + { "issue": "META-101", "action": "comment", "statusChange": "hold-for-human", "body": "Reconciliation audit 2026-07-22: the coChange.files set-semantics fix is present on feature/vr-639-640-spec-cli-prereqs, spike/v3d-ajv-validate, and release/0.4.4, but is NOT on origin/main (0.4.3 still ships `files: [string, string]` in types.ts). Marked Done on 2026-07-12 but never integrated to the canonical/published branch. Ships with release/0.4.4 (unmerged, no PR). Recommend keeping Done only if 'Done' means merged-to-branch; otherwise reopen until 0.4.4 publishes (see META-31)." }, + { "issue": "META-102", "action": "comment", "statusChange": "hold-for-human", "body": "Reconciliation audit 2026-07-22: the fileIndex repo-root-relative POSIX anchor is present on feature/spike/release-0.4.4 but absent from origin/main (0 matches for 'repository-root-relative' in schema/v1.json at 0.4.3). Done 2026-07-12 but not integrated/published. Ships with release/0.4.4." }, + { "issue": "META-97", "action": "comment", "statusChange": "none", "body": "Branch/worktree census delivered at docs/audits/worktree-reconciliation/2026-07-22/. 12 worktrees (3 live, 8 prunable, 1 primary-dirty), 14 local branches (4 with unique unmerged work: feature/vr-639-640, release/0.4.4, spike/v3d-ajv-validate, docs/readme-clarity-final). Zero repo/Linear mutations." } + ], + "cleanupCandidates": [ + { "target": "prunable worktree admin entries (8)", "safeAfter": "git worktree prune", "command": "git worktree prune -v", "blocking": "none — dirs already gone, branches retained" }, + { "target": "local branches: fix/npm-*, fix/agents-audit-bin-entrypoint, fix/ci-pnpm-version, release/0.4.2, release/v0.3, codex-root-workspace-json", "safeAfter": "confirm cherry=0 (done) + optional archive tag", "command": "git branch -d (only after tag/bundle)", "blocking": "archive tag recommended" }, + { "target": "spike/v3d-ajv-validate", "safeAfter": "release/0.4.4 merged + archive tag", "blocking": "release/0.4.4 integration" }, + { "target": "feature/vr-639-640-spec-cli-prereqs", "safeAfter": "unique working-tree content ported to release/0.4.4 line + preservation snapshot", "blocking": "CRITICAL — holds the only copy of uncommitted reconciliation" }, + { "target": "old May 2026 dangling stashes (11)", "safeAfter": "confirm superseded (all on merged history)", "command": "git reflog expire / gc (implicit)", "blocking": "none" } + ], + "unknowns": [ + "Live npm published versions — `npm view` blocked by local architecture-fence hook; 0.4.3 INFERRED from memory + origin/main.", + "Whether release/0.4.4 local == origin/release/0.4.4 (branch -vv shows tracking; not byte-verified).", + "Whether a dedicated Linear issue tracks the split-brain incident / 0.4.4 publish, or whether META-101's honest-correction section is the record of it.", + "The owning Linear issue for the @workspacejson/cli shim publish (references vreko#491 / HAC-75, not directly fetched this pass).", + "Content of the 4 recent dangling feature-branch stashes vs current working tree (not diffed)." + ], + "humanApprovalGates": [ + "G1: Ratify release/0.4.4 (not feature/vr-639-640) as the blessed 0.4.4 integration vehicle.", + "G2: Confirm the 2 unique CLI tests + CHANGELOG narrative must be ported before feature branch teardown.", + "G3: Decide META-101/102 status semantics (keep Done vs reopen-until-released).", + "G4: Confirm fixed-group version bump (feature tree bumps only spec→0.4.4; release/0.4.4 bumps all packages→0.4.4).", + "G5: Authorize any branch/worktree deletion (none performed in this pass)." + ] +} From 70d0679d1b42832e76fac2a3adaaf8dcf6ba741a Mon Sep 17 00:00:00 2001 From: Qwynn Marcelle Date: Wed, 22 Jul 2026 19:45:22 -0400 Subject: [PATCH 2/3] docs(audit): add remediation-results for 2026-07-22 preservation+integration pass Records: SAFE_DRIFT check, triple preservation, PR #19, validation (275 tests green), META-101/102 Done->In Review, and the G2 test/impl coupling that requires a follow-up authorization. --- .../2026-07-22/remediation-results.md | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md diff --git a/docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md b/docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md new file mode 100644 index 0000000..7eff217 --- /dev/null +++ b/docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md @@ -0,0 +1,196 @@ +# Remediation Results — Preservation & Integration Pass (2026-07-22) + +**Scope:** bounded first remediation pass authorized against `docs/audits/worktree-reconciliation/2026-07-22/`. +**Boundary honored:** no merge, no publish, no Done, no deletions, no stash drops, no force-push, no history rewrite, no unreachable-object removal. META-38 followed (impl/spec divergence surfaced, not auto-resolved). + +--- + +## Drift Check + +**Classification: `SAFE_DRIFT`.** The audit baseline held; the one refinement (release/0.4.4 already carrying a truthful CHANGELOG entry) reduced work rather than invalidating any operation. + +| Check | Expected (audit) | Observed | Result | +|---|---|---|---| +| Primary HEAD | `b6c092b` (feature/vr-639-640) | `b6c092b` | ✅ | +| Dirty unique work present | 2 CLI tests + CHANGELOG + validator.ts | all present | ✅ | +| META-101/102 impl on release/0.4.4 | present | `types.ts:101 files: string[]`, schema anchor ×2, cli pkg, validator.ts | ✅ | +| 2 CLI tests unique to dirty tree | yes | 0 matches in release/0.4.4 | ✅ | +| CHANGELOG material | unique | release/0.4.4 already has an accurate `[0.4.4]` entry; feature narrative adds unverifiable claims | ⚠️ refined | +| PR for release/0.4.4 | none | none | ✅ | +| META-101/102 status | Done | Done | ✅ | +| New worktrees/branches/commits invalidating audit | none | none | ✅ | + +**Refinement discovered:** the "two unique CLI tests" are **not standalone** — they are regression tests for two *uncommitted `cli.ts` behavior changes* (see Conflict Decisions). The original audit characterized them as tests-only; that was incomplete. Surfaced here, not silently resolved. + +--- + +## Preservation Artifacts + +The primary checkout working tree (`feature/vr-639-640-spec-cli-prereqs`) was preserved by three independent, non-destructive mechanisms. No `reset --hard`/`checkout .`/`clean`/`stash drop` was used; the source tree remained dirty and on `b6c092b` throughout. + +| Artifact | Location | Verification | Scope | +|---|---|---|---| +| **Git tag** `preserve/vr-639-640-worktree-2026-07-22` | commit `f5e3e0f` (via `git stash create`) | `git diff HEAD --stat` = `15 files, +179 −39`, matches live `git diff HEAD` | tracked changes (git object, GC-safe) | +| **Patch** `tracked-changes.patch` | `docs/audits/worktree-reconciliation/2026-07-22/preservation/` (committed `9619662`, pushed) | SHA-256 `77513874…449387`; 18747 B; `git apply --stat` = 15 files; contains both unique tests (grep=2) | tracked changes (text, remote-durable) | +| **Verbatim copy** `untracked-validator.ts` | same dir (committed `9619662`) | SHA-256 `fb9a9612…d74570`; `diff` vs `origin/main:…/validator.ts` = identical | the sole unique untracked file | +| **Manifest** `preservation/MANIFEST.md` | same dir (committed `9619662`) | recovery commands + hashes recorded | index of the above | + +**Recovery (no dependence on the current worktree path):** +- `git restore --source=preserve/vr-639-640-worktree-2026-07-22 --worktree -- .` (tracked), or +- `git checkout b6c092b && git apply docs/audits/worktree-reconciliation/2026-07-22/preservation/tracked-changes.patch`. + +**Exclusions:** `claudedocs/audit-aa-report.md` (pre-existing unrelated prior-audit doc); `docs/` audit artifacts (preserved via the audit commit). **No secrets/credentials/env values** in any artifact (verified). +**Note:** the git tag is currently local-only; the committed patch is the remote-durable copy. Push the tag with `git push origin preserve/vr-639-640-worktree-2026-07-22` if a remote git-object copy is also wanted. + +--- + +## Audit Artifact Commit + +- **Branch:** `docs/reconciliation-audit-2026-07-22` (off `origin/main` `5a0e37e`, in an isolated worktree so the dirty primary checkout was untouched). +- **Commit:** `9619662` — `docs(audit): record 2026-07-22 worktree/Linear reconciliation audit + preservation`. +- **Contents (docs-only, 6 files):** the 3 audit artifacts + `preservation/{tracked-changes.patch, untracked-validator.ts, MANIFEST.md}`. `git diff origin/main --name-only` = docs-only. No product source. +- **Pre-commit checks:** JSON valid; secret scan clean (only match was the `fix/npm-token-routing` *branch name*); repo/date references correct. +- **Pushed:** `origin/docs/reconciliation-audit-2026-07-22`. +- **Entry into canonical:** via PR (repo is PR-only). See Remaining Approval Gates. + +--- + +## Ported Changes + +| Item | Decision | Rationale | +|---|---|---| +| 2 unique CLI integration tests → release/0.4.4 | **NOT ported** | Proven to fail against release/0.4.4 (they test uncommitted `cli.ts` behavior). Porting them alone injects failing tests; porting the coupled `cli.ts` impl is outside the approved scope (tests + CHANGELOG only). See Conflict Decisions → `REQUIRES_HUMAN_DECISION`. | +| `0.4.4` CHANGELOG narrative → release/0.4.4 | **No change needed** | release/0.4.4 already carries a truthful, sufficient `[0.4.4]` entry covering the VR-639/640 reconciliation. The feature branch's longer narrative adds claims validation cannot support. See Conflict Decisions. | + +**Net effect on `release/0.4.4`: zero commits.** It was already the clean, rebased-on-main integration vehicle; nothing needed porting into it, and nothing portable-in-scope was missing. + +--- + +## Conflict Decisions + +**1. CLI tests are coupled to unshipped implementation (`REQUIRES_HUMAN_DECISION`).** +The feature working tree's `cli.ts` (`git diff HEAD -- packages/agents-audit/src/cli.ts`) makes two behavior changes the two tests lock in: +- reorders `--check` + `--dry-run` so the drift gate fires (exit 1) instead of the dry-run branch winning (exit 0); +- adds an `invalidFileMoved` recovery message branch. +release/0.4.4's `cli.ts` has neither (`if (options.dryRun)` is still first; no `invalidFileMoved`). +**Empirical proof** (tests inserted into release/0.4.4, run, then reverted to pristine): +``` +❯ still fails the drift gate when --check is combined with --dry-run + → expected +0 to be 1 +❯ surfaces the relocated invalid file when --force recovers a fresh generate + → expected 'Generated /repo/.agents/workspace.json' to contain '/repo/.agents/workspace.json.invalid.…' +Test Files 1 failed | 10 passed · Tests 2 failed | 60 passed +``` +**Decision:** do not port the tests, and do not port the coupled `cli.ts` impl (out of approved scope, and it is a genuine product/semantics change). Both behaviors + tests are fully preserved (tag + patch) and ready for a follow-up authorization. This is exactly the class META-38 says to surface, not resolve. + +**2. CHANGELOG — target already truthful (`no_change_needed`).** +release/0.4.4's `packages/spec/CHANGELOG.md` `[0.4.4] - Unreleased` already states: "Reconciled the strict packaged-schema validator with the VR-639/640 contract fixes that had diverged across earlier release branches," plus the fileIndex / coChange / version bullets. The feature branch's narrative additionally claims "0.4.2/0.4.3 were published from `spike/v3d-ajv-validate`" — imprecise (0.4.2 was published from `release/0.4.2` PR #10; the validator merely *originated* on spike). Per "do not preserve claims validation cannot support," that wording was **excluded**. No overwrite of release/0.4.4's history occurred. + +--- + +## Validation Results + +Run 2026-07-22 in the `release/0.4.4` worktree at head `3a77e1b` (pristine — the empirical test insert above was reverted before validation): + +| Command | Result | +|---|---| +| `pnpm -r build` | ✅ pass (all packages) | +| `pnpm -r typecheck` | ✅ pass — spec, rules, cli, agents-audit (`tsc --noEmit` each "Done") | +| `pnpm -r test` | ✅ **275 passed, 0 failed** — spec 36, cli 6, rules 173, agents-audit 60 | + +Acceptance-criterion spot checks on the built branch: +- META-101: `packages/spec/src/types.ts:101` → `files: string[]` (set), not tuple. +- META-102: `packages/spec/schema/v1.json` → "repository-root-relative" anchor present (2 sites). + +No failures introduced; no checks skipped. The `.npmrc` `${NPM_TOKEN}` warning is a benign local-env message, unrelated to correctness. Not run this pass: packaged-tarball publish verification (belongs to the Release workflow) and secret-scanning CI (GitHub-side). + +--- + +## Pull Request + +- **PR #19** — `release/0.4.4` → `main` — OPEN, `MERGEABLE`, not draft. + https://github.com/workspace-json/agents-audit/pull/19 +- Body: states it reconciles previously-unshipped work; lists validation results; links META-101/102/VR-639/VR-640 and META-31; explicitly notes 0.4.4 is **not** released and the 2 deferred tests. **No auto-close keywords** (merge ≠ release), confirmed by diff scan. +- Diff review: 28 files, all in-scope (spec fixes, `@workspacejson/cli`, changelogs, versions, lockfile). No unrelated changes, no reversions, no secrets, no private identifiers. +- Branch is **2 commits behind `origin/main`** (docs-only, PR #17) — use GitHub "Update branch" before merge. +- Not merged (per authorization). + +Audit-docs branch `docs/reconciliation-audit-2026-07-22` is pushed; its PR is a remaining step (see gates). + +--- + +## Linear Updates + +| Issue | Before | After | Actions | +|---|---|---|---| +| META-101 | Done (completed) | **In Review** (started, `completedAt: null`) | status change + evidence comment `030bed60` + PR #19 link `726e547b` | +| META-102 | Done (completed) | **In Review** (started, `completedAt: null`) | status change + evidence comment `30ba36d7` + PR #19 link `6e165a69` | + +Each comment records: the published-0.4.3 gap, the branch/PR carrying the fix, the specific file evidence, the validation, the remaining Done condition (merge + publish + verify), and a META-31 cross-reference. **Neither issue was marked Done.** "In Review" chosen because the team workflow has no "Merged" state (Triage/Scoped/Todo/In Progress/In Review/Done/Canceled/Duplicate) — documented as a concrete case for META-31. + +Not modified: META-97 (census anchor) — the audit proposed a comment there, but posting it was outside this pass's enumerated Linear scope (META-101/102 only). Left for the next authorization. + +--- + +## Deviations From Audit + +1. **CHANGELOG port became a no-op.** The audit assumed the 0.4.4 narrative was missing from release/0.4.4; it is already present and truthful. Reconciliation = confirming that and excluding the feature branch's unverifiable claims. +2. **CLI tests not ported.** The audit listed them as portable "tests only." Execution proved they are coupled to unshipped `cli.ts` behavior; porting was therefore out of scope. Reclassified to `REQUIRES_HUMAN_DECISION`. +3. **release/0.4.4 not refreshed onto origin/main.** Left 2-behind (docs-only) rather than performing an unnecessary history op; flagged for "Update branch" at merge time. PR is `MERGEABLE` regardless. +4. **Personal absolute path in committed audit docs.** `/Users/user1/...` appears in `repository-reconciliation.json` and `preservation/MANIFEST.md` as legitimate provenance evidence. Not scrubbed (would falsify the record) — but recommend a scrub pass before this repo goes public as the `workspacejson` standard. + +--- + +## Remaining Approval Gates + +- **G1 — vehicle:** resolved by this authorization (release/0.4.4 is the vehicle). +- **G2 — port the 2 tests + coupled `cli.ts` behaviors:** **UNRESOLVED — needs decision.** Approve porting the two `cli.ts` hunks (drift-gate reorder + `invalidFileMoved` messaging) *and* their tests as a follow-up, or rule those behaviors out of 0.4.4. Preserved and ready either way. +- **G3 — Done semantics:** applied as directed (Done→In Review). Return to Done only post-publish + verify. +- **G4 — fixed-group versioning:** release/0.4.4 already bumps all packages to 0.4.4 (self-consistent); the feature tree's spec-only bump is superseded. No action taken; confirm at release time. +- **G5 — deletions:** none performed; deferred (see below). +- **PR merges:** PR #19 (release) and a PR for `docs/reconciliation-audit-2026-07-22` both await human authorization. `gh pr create --base main --head docs/reconciliation-audit-2026-07-22` opens the docs PR. + +--- + +## Explicitly Deferred Cleanup (nothing deleted this pass) + +| Object | State | Why deferred | +|---|---|---| +| **Worktrees** — 8 prunable admin entries (`agents-audit-npm-*`, `-release-042`, `-v3d-ajv`, `-v3d-baseline`, `hac-181-prechange`), + `-bin-entrypoint`, `-readme-final`, `-release-044`, primary | all left in place | `git worktree prune` deferred to post-merge cleanup authorization | +| **Local branches** — `fix/npm-access-command`, `fix/npm-publish-access`, `fix/npm-publisher-preflight`, `fix/npm-token-routing`, `fix/agents-audit-bin-entrypoint`, `fix/ci-pnpm-version`, `release/0.4.2`, `release/v0.3`, `codex-root-workspace-json` (all integrated) | not deleted | cleanup requires separate authorization | +| **`spike/v3d-ajv-validate`** | not deleted | retire only after 0.4.4 merges + archive tag | +| **`feature/vr-639-640-spec-cli-prereqs`** + its dirty tree | not deleted, still dirty | holds the deferred G2 work; preserved but not yet integrated | +| **Stashes** | `git stash list` empty; 15 dangling stash-shaped commits (incl. 4 recent feature-branch WIP) | none dropped; unreachable-object removal explicitly out of scope | +| **`preserve/…` tag** | created | intentionally retained | + +--- + +## Final State + +| Item | Value | +|---|---| +| Canonical branch commit | `origin/main` `5a0e37e` — **unchanged** | +| `release/0.4.4` commit | `3a77e1b` — **unchanged** (zero commits added) | +| PR status | **#19 OPEN / MERGEABLE** (not merged); docs PR pending | +| Validation status | build ✅ · typecheck ✅ · test **275/275** ✅ | +| META-101 | **In Review** (was Done) | +| META-102 | **In Review** (was Done) | +| Remaining dirty worktree | primary `feature/vr-639-640` still dirty (18 entries), HEAD `b6c092b` — **untouched** | +| Preservation status | ✅ triple-preserved (tag `f5e3e0f` + committed patch + verbatim copy) | +| Audit artifact status | ✅ committed `9619662`, pushed `origin/docs/reconciliation-audit-2026-07-22` | +| Remaining worktrees | 12 (unchanged) | +| Branches with unique unmerged work | `feature/vr-639-640` (4), `release/0.4.4` (4, in PR #19), `spike/v3d-ajv-validate` (3), `docs/readme-clarity-final` (1, PR #18), `docs/reconciliation-audit-2026-07-22` (1) | +| Any unique work at risk? | **No.** The only at-risk item (feature dirty tree) is triple-preserved. | + +--- + +## Recommendation for Next Authorization + +### `REQUIRES_HUMAN_DECISION` + +Two decisions block a clean close: + +1. **G2 — the two CLI tests + their `cli.ts` behaviors.** They cannot land without an implementation/semantics change (drift-gate reorder for `--check --dry-run`, and `invalidFileMoved` recovery messaging) that exceeds this pass's approved scope. Decide: (a) authorize porting both hunks + tests into a follow-up PR, or (b) rule the behaviors out of 0.4.4. Work is preserved either way. +2. **Merge/publish path for PR #19.** Validated and mergeable, but merging + publishing 0.4.4 was explicitly out of scope. This is the step that will actually let META-101/102 return to Done. + +Everything mechanically safe in this pass is done: preservation, audit commit, PR #19, validation evidence, and the Linear correction. **Do not merge, publish, delete, or port implementation until the above is authorized.** From 40f4c84963d15da7af819d6df775989f30221f2e Mon Sep 17 00:00:00 2001 From: Qwynn Marcelle Date: Wed, 22 Jul 2026 20:13:54 -0400 Subject: [PATCH 3/3] docs(audit): append 0.4.4 release-execution addendum (merge, release, verify, Linear Done) --- .../2026-07-22/remediation-results.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md b/docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md index 7eff217..07ca12c 100644 --- a/docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md +++ b/docs/audits/worktree-reconciliation/2026-07-22/remediation-results.md @@ -194,3 +194,83 @@ Two decisions block a clean close: 2. **Merge/publish path for PR #19.** Validated and mergeable, but merging + publishing 0.4.4 was explicitly out of scope. This is the step that will actually let META-101/102 return to Done. Everything mechanically safe in this pass is done: preservation, audit commit, PR #19, validation evidence, and the Linear correction. **Do not merge, publish, delete, or port implementation until the above is authorized.** + +--- + +# Release Execution Addendum — 2026-07-23 + +This section is **appended** (the original evidentiary record above is unchanged). It records the governed `0.4.4` merge, publish, verification, and Linear reconciliation pass that followed, and supersedes the previous pass's `REQUIRES_HUMAN_DECISION` recommendation. + +Pre-merge drift: **`SAFE_DRIFT`** — PR #19 MERGEABLE/CLEAN, CI `test (20)`+`test (22)` green on the merge ref, excluded CLI behaviors absent, versions correct, META-101/102 still In Review, preservation intact. + +## Release Merge + +- **PR:** #19 (`release/0.4.4` → `main`). +- **Merge commit:** `d0a19f6` (merge commit; repo's standard "Merge pull request" policy, matching history #10–#17). +- **Merge-candidate validation:** locally merged `origin/main` into `release/0.4.4` (no-commit) → `pnpm -r build` ✅, `pnpm -r typecheck` ✅, `pnpm -r test` **275 passed / 0 failed** (spec 36, cli 6, rules 173, agents-audit 60); merge aborted to keep the branch pristine. GitHub required checks `test (20)`/`test (22)` also green on the PR merge ref. +- Post-merge `origin/main` carries: spec `0.4.4`, `types.ts files: string[]`, schema anchor ×2, `@workspacejson/cli` present, excluded CLI display messaging **absent**. + +## Published Release + +- **Version:** `@workspacejson/spec@0.4.4`, `@workspacejson/rules@0.4.4`, `agents-audit@0.4.4`. +- **Not published:** `@workspacejson/cli` (`private: true`, `0.0.1`) — in-repo scaffold only; correctly skipped by changesets. +- **Tag:** `v0.4.4` (annotated, `7d562fa`) on `d0a19f6`. +- **Workflow:** Release run `29967929171` via `workflow_dispatch` on `main` — the repo's established path (the tag trigger did not fire; every prior release incl. 0.4.3 used dispatch, and no `v0.4.3` tag ever existed). The `Publish packages` step **succeeded**; changesets reported `packages published successfully: agents-audit@0.4.4, @workspacejson/rules@0.4.4, @workspacejson/spec@0.4.4`. +- **Known false-red:** the post-publish `Verify published packages from the registry` step failed on the registry-propagation race (documented flake); the publish itself succeeded and propagation completed within ~1 min. `latest=0.4.4` confirmed via independent HTTPS reads. +- **Integrity (published tarball shasums):** spec `8a3df59c…9f65`, rules `f77e1d60…0ebb`, agents-audit `263f9b84…1ad5` — all matched on download. + +## Published-Artifact Verification + +Clean-environment procedure: downloaded each `0.4.4` tarball, verified shasum, extracted; installed `ajv` into a throwaway app and imported the **published** `@workspacejson/spec` dist. + +- Versions: all three report `0.4.4`. ✅ +- **META-101:** published `schema/v1.json` `coChange.items.files` documented "Unordered pair (set semantics — position is NOT meaningful; join by membership, not index)", `minItems:2/maxItems:2`; `types.ts` → `files: string[]`. Functional smoke: a pair validates identically in `[a,b]` and `[b,a]`, a 3-file entry is rejected, `validate({})` rejected. ✅ +- **META-102:** "repository-root-relative POSIX path" anchor at 2 sites in published `schema/v1.json`; strict AJV validator loads and enforces at runtime. ✅ +- **Contents clean:** no `/Users/`, `node_modules/`, dotenv, npmrc, tokens, or keys in any tarball; spec = 15 files (matches `fileCount`). +- **Excluded behavior absent:** published `agents-audit` dist has neither excluded display string ("moved aside", "was not recovered"); `invalidFileMoved` appears only as the pre-existing generate result field (5 refs already in 0.4.3), not the deferred CLI messaging. + +## Linear Final State + +- **META-101:** In Review → **Done** (`completedAt 2026-07-23T00:10`), closing comment `b37f6f89` with published-artifact evidence + PR #19 link. +- **META-102:** In Review → **Done** (`completedAt 2026-07-23T00:10`), closing comment `e12654ab`. +- Done applied **only after** published-artifact verification (In Review → released → Done). Both comments cite **META-31** as the concrete Merged-vs-Done case. +- **META-157** (new, Backlog, Medium, not started): the deferred CLI behaviors + tests follow-up; PR #19 linked. + +## Documentation Merge + +- **PR #20** (`docs/reconciliation-audit-2026-07-22` → `main`): docs-only, confirmed. This addendum is committed to that branch, then PR #20 is merged as the final governed step of this pass (merge commit on `main`). + +## Preserved Deferred Work + +Nothing lost; the deferred CLI work is triple-preserved and tracked in **META-157**: +- CLI implementation changes: `cli.ts` drift-gate reorder + `invalidFileMoved` messaging. +- Coupled tests: two `cli.integration.test.ts` cases. +- Preservation tag `preserve/vr-639-640-worktree-2026-07-22` (`f5e3e0f`); patch `preservation/tracked-changes.patch` (SHA-256 `77513874…449387`); manifest `preservation/MANIFEST.md`; verbatim `preservation/untracked-validator.ts`. +- Recovery: `git restore --source=preserve/vr-639-640-worktree-2026-07-22 --worktree -- .` or `git checkout b6c092b && git apply …/tracked-changes.patch`. + +## Cleanup Readiness + +Cleanup is **prepared, not executed.** Per-target status: + +| Target | Unique work? | Integrated? | Preserved? | Dependency remaining? | Eligible? | Precondition | +|---|---|---|---|---|---|---| +| `release/0.4.4` branch + `/private/tmp/agents-audit-release-044` worktree | was 4 commits | **Yes** (merged `d0a19f6`, published) | n/a | none | **Yes** | `git worktree remove` then `git branch -d release/0.4.4` (archive tag optional) | +| `spike/v3d-ajv-validate` (+ worktree) | 3 commits, superseded | via 0.4.2 + 0.4.4 | tag `archive/spike-v3d-ajv-validate` | none | **Yes** | keep archive tag; `git branch -D` | +| `feature/vr-639-640-spec-cli-prereqs` (primary, dirty) | committed superseded; **dirty = META-157 work** | spec parts via 0.4.4 | tag + patch | **META-157 open** | **No** | hold until META-157 lands; never `checkout .`/`reset --hard`/`clean` | +| `fix/npm-*` (4), `fix/agents-audit-bin-entrypoint`, `fix/ci-pnpm-version`, `release/0.4.2`, `release/v0.3`, `codex-root-workspace-json` | none (`git cherry`=0) | Yes | git history | none | **Yes** | optional archive tag; `git branch -d` | +| 8 prunable worktree admin entries (missing dirs) | none | n/a | n/a | none | **Yes** | `git worktree prune -v` | +| `docs/readme-clarity-final` (PR #18) | 1 commit | No | n/a | **PR #18 open** | **No** | resolve PR #18 first | +| `docs/reconciliation-audit-2026-07-22` (PR #20) | 2 commits | on merge | n/a | PR #20 | after merge | delete branch after PR #20 merges | +| `preserve/…` tag, dangling stashes, `v0.4.4` tag | preservation / history | — | — | META-157 (preserve tag) | **No** | retain; not cleanup targets this cycle | + +No cleanup command was run; a separate authorization is required to execute it. + +## Final Outcome + +- Canonical `origin/main`: **`d0a19f6`** (0.4.4 merged). +- Published + verified: `@workspacejson/spec`/`rules`/`agents-audit@0.4.4`. +- META-101, META-102: **Done** (post-verification). META-157: created for the deferred CLI work. +- PR #20: merged (this addendum is its final content). +- Primary dirty checkout, preservation tag, stashes, worktrees, branches: **all intact** — cleanup deferred to a separate authorization. + +**Result: `AUTHORIZE_FINAL_CLEANUP`.**