fix(notes): anchor archive seals to prior Git state

This commit is contained in:
Tianyi Cui
2026-07-27 00:01:39 +08:00
parent 0561647ed5
commit d52f8bfdfe
4 changed files with 72 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ import {
parseArchiveManifest,
renderArchiveManifest,
validateArchiveArtifacts,
validateArchiveManifestExtension,
type ArchiveManifest,
} from './archived-agent-notes.ts'
@@ -54,6 +55,29 @@ describe('archived Agent Notes', () => {
)
})
it('rejects replacing manifest seals alongside changed archive content', () => {
const artifacts = fixture()
const initial = extendArchiveManifest({ version: 1, files: {} }, artifacts)
const baseline: ArchiveManifest = { version: 1, files: initial.files }
const path = 'process/2026-07-26-example.md'
const changedArtifacts = new Map(artifacts)
changedArtifacts.set(path, Buffer.from('changed'))
const replacement = extendArchiveManifest({ version: 1, files: {} }, changedArtifacts)
const current: ArchiveManifest = { version: 1, files: replacement.files }
expect(extendArchiveManifest(current, changedArtifacts).errors).toEqual([])
expect(validateArchiveManifestExtension(baseline, current)).toEqual([
`${path}: sealed manifest hash changed`,
])
const removed: ArchiveManifest = {
version: 1,
files: Object.fromEntries(Object.entries(current.files).filter(([candidate]) => candidate !== path)),
}
expect(validateArchiveManifestExtension(baseline, removed)).toContain(
`${path}: sealed manifest entry is missing`,
)
})
it('round-trips the deterministic manifest schema', () => {
const content = renderArchiveManifest({ 'process/z.md': `sha256:${'a'.repeat(64)}` })
expect(parseArchiveManifest(content)).toEqual({