diff --git a/dist/commitlore.mjs b/dist/commitlore.mjs index 3de5da0a..1c467dc9 100755 --- a/dist/commitlore.mjs +++ b/dist/commitlore.mjs @@ -15996,6 +15996,19 @@ import { createHash as createHash3 } from "node:crypto"; var PROVENANCE_KEY3 = "Provenance"; var sha2562 = (input) => createHash3("sha256").update(input).digest("hex"); var recordIdOf = (record2) => record2.trailers.find((t) => t.key === "Record-Id")?.value; +var recordIdSeed = (record2) => record2.trailers.filter((trailer) => trailer.key !== "Record-Id").map((trailer) => JSON.stringify([trailer.key, trailer.value])).sort().join("\n"); +var MINTED_ID_CHARS = 12; +var mintRecordId = (record2, reservedIds) => { + const seed = recordIdSeed(record2); + let probe = 0; + while (true) { + const input = probe === 0 ? seed : `${seed} +${probe}`; + const candidate = `r-${sha2562(input).slice(0, MINTED_ID_CHARS)}`; + if (!reservedIds.has(candidate)) return candidate; + probe += 1; + } +}; var captureCanonicalTuple = (trailers) => { const keys = trailers.filter((t) => t.key !== "Record-Id" && t.key !== "Evidence" && t.key !== "Provenance").map((t) => `${t.key.toLowerCase()}=${t.value.toLowerCase()}`).sort().join("|"); return keys; @@ -16007,18 +16020,19 @@ var classifyResult = (accepted, rejected) => { }; var loadCaptureVerificationHistory = (cwd) => { try { - const activeRecordIds = /* @__PURE__ */ new Set(); + const recordIds = /* @__PURE__ */ new Set(); const activeCanonicalTuples = /* @__PURE__ */ new Set(); - const queryResult = runQuery({ cwd, noIndex: true }); + const queryResult = runQuery({ cwd, noIndex: true, allHistory: true }); for (const rec of queryResult.records) { const idTrailer = rec.trailers.find((t) => t.key === "Record-Id"); - if (idTrailer) activeRecordIds.add(idTrailer.value); + if (idTrailer) recordIds.add(idTrailer.value); + if (rec.lifecycle !== "active") continue; const tuple = rec.trailers.filter( (t) => t.key !== "Record-Id" && t.key !== "Evidence" && t.key !== "Provenance" ).map((t) => `${t.key.toLowerCase()}=${t.value.toLowerCase()}`).sort().join("|"); activeCanonicalTuples.add(tuple); } - return { activeRecordIds, activeCanonicalTuples }; + return { recordIds, activeCanonicalTuples }; } catch { return null; } @@ -16103,15 +16117,16 @@ var verifyCaptureRecords = (opts) => { persist(result2); return result2; } - const { activeRecordIds, activeCanonicalTuples } = history; + const reservedRecordIds = new Set(history.recordIds); + const { activeCanonicalTuples } = history; const verifyResult = verifyDraft(draft, { transcript, diff }); for (const verified of verifyResult.accepted) { const id = recordIdOf(verified.record); - if (id && activeRecordIds.has(id)) { + if (id && reservedRecordIds.has(id)) { rejected.push({ record: verified.record, reason: "duplicate-record-id", - detail: `Record-Id "${id}" already exists in active records` + detail: `Record-Id "${id}" already exists in repository history` }); continue; } @@ -16125,6 +16140,7 @@ var verifyCaptureRecords = (opts) => { continue; } accepted.push(verified); + if (id) reservedRecordIds.add(id); } if (resolvePolicy(cwd).policy.mode === "auto") { for (const verified of accepted) { @@ -16135,6 +16151,12 @@ var verifyCaptureRecords = (opts) => { verified.record.trailers = trailers; } } + for (const verified of accepted) { + if (recordIdOf(verified.record) !== void 0) continue; + const id = mintRecordId(verified.record, reservedRecordIds); + verified.record.trailers = [...verified.record.trailers, { key: "Record-Id", value: id }]; + reservedRecordIds.add(id); + } for (const rejectedRec of verifyResult.rejected) { rejected.push({ record: rejectedRec.record, @@ -16444,25 +16466,23 @@ var readHistoricalRecords = (cwd) => { }); }; var verificationHistory = (records) => { - const realIds = /* @__PURE__ */ new Set(); + const recordIds = /* @__PURE__ */ new Set(); const stream = records.map((record2, index) => { const id = record2.trailers.find((trailer) => trailer.key === "Record-Id")?.value; - if (id !== void 0) realIds.add(id); + if (id !== void 0) recordIds.add(id); return { sha: record2.sha, committedAt: record2.committedAt, trailers: id === void 0 ? [{ key: "Record-Id", value: `${SYNTHETIC_HISTORY_ID}${record2.sha}:${index}` }, ...record2.trailers] : record2.trailers }; }); - const activeRecordIds = /* @__PURE__ */ new Set(); const activeCanonicalTuples = /* @__PURE__ */ new Set(); for (const state of foldLifecycle(stream, { at: /* @__PURE__ */ new Date() })) { if (state.lifecycle !== "active") continue; - if (realIds.has(state.recordId)) activeRecordIds.add(state.recordId); const tuple = captureCanonicalTuple(state.resolvedTrailers); if (tuple !== "") activeCanonicalTuples.add(tuple); } - return { activeRecordIds, activeCanonicalTuples }; + return { recordIds, activeCanonicalTuples }; }; var historiesBeforeCommit = (cwd) => { const records = readHistoricalRecords(cwd); diff --git a/dist/core/capture-shadow.js b/dist/core/capture-shadow.js index d0657342..a90cd610 100644 --- a/dist/core/capture-shadow.js +++ b/dist/core/capture-shadow.js @@ -96,13 +96,13 @@ const readHistoricalRecords = (cwd) => { return [{ sha, committedAt, trailers }]; }); }; -/** Build exactly the two active-record sets the ordinary verifier accepts. */ +/** Build the historical identity and active-content sets the ordinary verifier accepts. */ const verificationHistory = (records) => { - const realIds = new Set(); + const recordIds = new Set(); const stream = records.map((record, index) => { const id = record.trailers.find((trailer) => trailer.key === 'Record-Id')?.value; if (id !== undefined) - realIds.add(id); + recordIds.add(id); return { sha: record.sha, committedAt: record.committedAt, @@ -111,18 +111,15 @@ const verificationHistory = (records) => { : record.trailers, }; }); - const activeRecordIds = new Set(); const activeCanonicalTuples = new Set(); for (const state of foldLifecycle(stream, { at: new Date() })) { if (state.lifecycle !== 'active') continue; - if (realIds.has(state.recordId)) - activeRecordIds.add(state.recordId); const tuple = captureCanonicalTuple(state.resolvedTrailers); if (tuple !== '') activeCanonicalTuples.add(tuple); } - return { activeRecordIds, activeCanonicalTuples }; + return { recordIds, activeCanonicalTuples }; }; /** The ordinary verifier sees only records made before the commit being replayed. */ const historiesBeforeCommit = (cwd) => { diff --git a/dist/core/capture-shadow.js.map b/dist/core/capture-shadow.js.map index d6c8bcbc..162c0fbe 100644 --- a/dist/core/capture-shadow.js.map +++ b/dist/core/capture-shadow.js.map @@ -1 +1 @@ -{"version":3,"file":"capture-shadow.js","sourceRoot":"","sources":["../../src/core/capture-shadow.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"capture-shadow.js","sourceRoot":"","sources":["../../src/core/capture-shadow.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/core/capture-verify.d.ts b/dist/core/capture-verify.d.ts index 7cf33007..7b4c42eb 100644 --- a/dist/core/capture-verify.d.ts +++ b/dist/core/capture-verify.d.ts @@ -49,7 +49,9 @@ export interface VerifyCaptureResult { } /** The duplicate-check view used by capture verification. */ export interface CaptureVerificationHistory { - activeRecordIds: Set; + /** Every identity declared in repository history, including retired records. */ + recordIds: Set; + /** Canonical tuples of active records, which are the only duplicate content. */ activeCanonicalTuples: Set; } /** @@ -72,7 +74,7 @@ export declare const loadCaptureVerificationHistory: (cwd: string) => CaptureVer * * Delegates to `verifyDraft` for each record, then performs: * - Source hash verification (transcript/diff match what prepare stored) - * - Duplicate Record-Id detection against active records + * - Duplicate Record-Id detection against every historical identity * - Canonical duplicate detection * - Notes availability check (unfetched → incomplete) * diff --git a/dist/core/capture-verify.js b/dist/core/capture-verify.js index e551b212..a1881764 100644 --- a/dist/core/capture-verify.js +++ b/dist/core/capture-verify.js @@ -29,6 +29,52 @@ import { notesAvailability } from './notes.js'; const sha256 = (input) => createHash('sha256').update(input).digest('hex'); /** Extract Record-Id from a draft record's trailers. */ const recordIdOf = (record) => record.trailers.find((t) => t.key === 'Record-Id')?.value; +/** + * Canonical committed content used to derive a missing identity. Evidence is + * deliberately absent: it proves the draft, but never reaches the commit. + * Sorting makes the identity depend on the record rather than its JSON field + * order, and Record-Id is omitted because this is only called when it is + * missing. + */ +const recordIdSeed = (record) => record.trailers + .filter((trailer) => trailer.key !== 'Record-Id') + .map((trailer) => JSON.stringify([trailer.key, trailer.value])) + .sort() + .join('\n'); +/** + * How much of the digest becomes the identity. + * + * A full sha256 is 64 characters, and this identity is not a secret — it is + * printed on every commit and again on every injected line, where the renderer + * pads it into a column. At 64 characters it would dominate the payload and + * push real record content out of the injection budget, so the budget would be + * spent on identity rather than on what was decided. + * + * Twelve keeps it legible beside the hand-written ids already in these + * histories, and the birthday bound is far below where it matters — a + * repository would need on the order of a million records before a collision + * became likely. The probe below handles that case anyway, so shortening + * trades no correctness for a payload that fits. + */ +const MINTED_ID_CHARS = 12; +/** + * Mint an identity deterministically from the record that will be committed. + * A pre-existing identity can be an extraordinarily unlikely digest collision, + * or a deliberately claimed value, so retry with a deterministic probe rather + * than silently reusing it. The current history makes the probe choice stable + * for a retry while still reserving every historical identity. + */ +const mintRecordId = (record, reservedIds) => { + const seed = recordIdSeed(record); + let probe = 0; + while (true) { + const input = probe === 0 ? seed : `${seed}\n${probe}`; + const candidate = `r-${sha256(input).slice(0, MINTED_ID_CHARS)}`; + if (!reservedIds.has(candidate)) + return candidate; + probe += 1; + } +}; /** * Canonical identity tuple for de-duplication: lowercased key + value, no scope * (scope is path, handled by the query layer). Two records with the same @@ -57,13 +103,15 @@ const classifyResult = (accepted, rejected) => { */ export const loadCaptureVerificationHistory = (cwd) => { try { - const activeRecordIds = new Set(); + const recordIds = new Set(); const activeCanonicalTuples = new Set(); - const queryResult = runQuery({ cwd, noIndex: true }); + const queryResult = runQuery({ cwd, noIndex: true, allHistory: true }); for (const rec of queryResult.records) { const idTrailer = rec.trailers.find((t) => t.key === 'Record-Id'); if (idTrailer) - activeRecordIds.add(idTrailer.value); + recordIds.add(idTrailer.value); + if (rec.lifecycle !== 'active') + continue; const tuple = rec.trailers .filter((t) => t.key !== 'Record-Id' && t.key !== 'Evidence' && @@ -73,7 +121,7 @@ export const loadCaptureVerificationHistory = (cwd) => { .join('|'); activeCanonicalTuples.add(tuple); } - return { activeRecordIds, activeCanonicalTuples }; + return { recordIds, activeCanonicalTuples }; } catch { return null; @@ -87,7 +135,7 @@ export const loadCaptureVerificationHistory = (cwd) => { * * Delegates to `verifyDraft` for each record, then performs: * - Source hash verification (transcript/diff match what prepare stored) - * - Duplicate Record-Id detection against active records + * - Duplicate Record-Id detection against every historical identity * - Canonical duplicate detection * - Notes availability check (unfetched → incomplete) * @@ -182,18 +230,22 @@ export const verifyCaptureRecords = (opts) => { persist(result); return result; } - const { activeRecordIds, activeCanonicalTuples } = history; + // Do not mutate a caller-provided historical snapshot: shadow reuses one + // across many verification calls. This local reservation set also keeps + // identities distinct when a permissive policy permits several records. + const reservedRecordIds = new Set(history.recordIds); + const { activeCanonicalTuples } = history; // 4. Delegate to verifyDraft for evidence/grammar checking const verifyResult = verifyDraft(draft, { transcript, diff }); // Process accepted records — additional checks for (const verified of verifyResult.accepted) { const id = recordIdOf(verified.record); // Check duplicate Record-Id - if (id && activeRecordIds.has(id)) { + if (id && reservedRecordIds.has(id)) { rejected.push({ record: verified.record, reason: 'duplicate-record-id', - detail: `Record-Id "${id}" already exists in active records`, + detail: `Record-Id "${id}" already exists in repository history`, }); continue; } @@ -208,6 +260,8 @@ export const verifyCaptureRecords = (opts) => { continue; } accepted.push(verified); + if (id) + reservedRecordIds.add(id); } // ADR-0030. In `auto` the host stages without asking, so nobody read this // record — whatever the model wrote in its `Provenance:` line. Stamping @@ -224,6 +278,18 @@ export const verifyCaptureRecords = (opts) => { verified.record.trailers = trailers; } } + // The only safe place to mint is after every evidence, vocabulary, and + // duplicate-content check above. A rejected draft remains exactly the + // discarded proposal it arrived as; it never consumes or reveals an id. + // This is intentionally beside provenance stamping: both are facts the + // unattended pipeline establishes about a record it has accepted. + for (const verified of accepted) { + if (recordIdOf(verified.record) !== undefined) + continue; + const id = mintRecordId(verified.record, reservedRecordIds); + verified.record.trailers = [...verified.record.trailers, { key: 'Record-Id', value: id }]; + reservedRecordIds.add(id); + } // Collect rejections from verifyDraft for (const rejectedRec of verifyResult.rejected) { rejected.push({ diff --git a/dist/core/capture-verify.js.map b/dist/core/capture-verify.js.map index 87491750..149b563d 100644 --- a/dist/core/capture-verify.js.map +++ b/dist/core/capture-verify.js.map @@ -1 +1 @@ -{"version":3,"file":"capture-verify.js","sourceRoot":"","sources":["../../src/core/capture-verify.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"capture-verify.js","sourceRoot":"","sources":["../../src/core/capture-verify.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/core/capture-shadow.ts b/src/core/capture-shadow.ts index 9a63a398..77544f5c 100644 --- a/src/core/capture-shadow.ts +++ b/src/core/capture-shadow.ts @@ -173,12 +173,12 @@ const readHistoricalRecords = (cwd: string): HistoricalRecord[] | null => { }); }; -/** Build exactly the two active-record sets the ordinary verifier accepts. */ +/** Build the historical identity and active-content sets the ordinary verifier accepts. */ const verificationHistory = (records: readonly HistoricalRecord[]): CaptureVerificationHistory => { - const realIds = new Set(); + const recordIds = new Set(); const stream: StaleRecord[] = records.map((record, index) => { const id = record.trailers.find((trailer) => trailer.key === 'Record-Id')?.value; - if (id !== undefined) realIds.add(id); + if (id !== undefined) recordIds.add(id); return { sha: record.sha, committedAt: record.committedAt, @@ -188,15 +188,13 @@ const verificationHistory = (records: readonly HistoricalRecord[]): CaptureVerif : record.trailers, }; }); - const activeRecordIds = new Set(); const activeCanonicalTuples = new Set(); for (const state of foldLifecycle(stream, { at: new Date() })) { if (state.lifecycle !== 'active') continue; - if (realIds.has(state.recordId)) activeRecordIds.add(state.recordId); const tuple = captureCanonicalTuple(state.resolvedTrailers); if (tuple !== '') activeCanonicalTuples.add(tuple); } - return { activeRecordIds, activeCanonicalTuples }; + return { recordIds, activeCanonicalTuples }; }; /** The ordinary verifier sees only records made before the commit being replayed. */ diff --git a/src/core/capture-verify.ts b/src/core/capture-verify.ts index e463a04d..e71e374d 100644 --- a/src/core/capture-verify.ts +++ b/src/core/capture-verify.ts @@ -64,7 +64,9 @@ export interface VerifyCaptureResult { /** The duplicate-check view used by capture verification. */ export interface CaptureVerificationHistory { - activeRecordIds: Set; + /** Every identity declared in repository history, including retired records. */ + recordIds: Set; + /** Canonical tuples of active records, which are the only duplicate content. */ activeCanonicalTuples: Set; } @@ -79,6 +81,55 @@ const sha256 = (input: string): string => const recordIdOf = (record: DraftRecord): string | undefined => record.trailers.find((t) => t.key === 'Record-Id')?.value; +/** + * Canonical committed content used to derive a missing identity. Evidence is + * deliberately absent: it proves the draft, but never reaches the commit. + * Sorting makes the identity depend on the record rather than its JSON field + * order, and Record-Id is omitted because this is only called when it is + * missing. + */ +const recordIdSeed = (record: DraftRecord): string => + record.trailers + .filter((trailer) => trailer.key !== 'Record-Id') + .map((trailer) => JSON.stringify([trailer.key, trailer.value])) + .sort() + .join('\n'); + +/** + * How much of the digest becomes the identity. + * + * A full sha256 is 64 characters, and this identity is not a secret — it is + * printed on every commit and again on every injected line, where the renderer + * pads it into a column. At 64 characters it would dominate the payload and + * push real record content out of the injection budget, so the budget would be + * spent on identity rather than on what was decided. + * + * Twelve keeps it legible beside the hand-written ids already in these + * histories, and the birthday bound is far below where it matters — a + * repository would need on the order of a million records before a collision + * became likely. The probe below handles that case anyway, so shortening + * trades no correctness for a payload that fits. + */ +const MINTED_ID_CHARS = 12; + +/** + * Mint an identity deterministically from the record that will be committed. + * A pre-existing identity can be an extraordinarily unlikely digest collision, + * or a deliberately claimed value, so retry with a deterministic probe rather + * than silently reusing it. The current history makes the probe choice stable + * for a retry while still reserving every historical identity. + */ +const mintRecordId = (record: DraftRecord, reservedIds: ReadonlySet): string => { + const seed = recordIdSeed(record); + let probe = 0; + while (true) { + const input = probe === 0 ? seed : `${seed}\n${probe}`; + const candidate = `r-${sha256(input).slice(0, MINTED_ID_CHARS)}`; + if (!reservedIds.has(candidate)) return candidate; + probe += 1; + } +}; + /** * Canonical identity tuple for de-duplication: lowercased key + value, no scope * (scope is path, handled by the query layer). Two records with the same @@ -110,12 +161,14 @@ const classifyResult = ( */ export const loadCaptureVerificationHistory = (cwd: string): CaptureVerificationHistory | null => { try { - const activeRecordIds: Set = new Set(); + const recordIds: Set = new Set(); const activeCanonicalTuples: Set = new Set(); - const queryResult = runQuery({ cwd, noIndex: true }); + const queryResult = runQuery({ cwd, noIndex: true, allHistory: true }); for (const rec of queryResult.records) { const idTrailer = rec.trailers.find((t) => t.key === 'Record-Id'); - if (idTrailer) activeRecordIds.add(idTrailer.value); + if (idTrailer) recordIds.add(idTrailer.value); + + if (rec.lifecycle !== 'active') continue; const tuple = rec.trailers .filter( @@ -129,7 +182,7 @@ export const loadCaptureVerificationHistory = (cwd: string): CaptureVerification .join('|'); activeCanonicalTuples.add(tuple); } - return { activeRecordIds, activeCanonicalTuples }; + return { recordIds, activeCanonicalTuples }; } catch { return null; } @@ -144,7 +197,7 @@ export const loadCaptureVerificationHistory = (cwd: string): CaptureVerification * * Delegates to `verifyDraft` for each record, then performs: * - Source hash verification (transcript/diff match what prepare stored) - * - Duplicate Record-Id detection against active records + * - Duplicate Record-Id detection against every historical identity * - Canonical duplicate detection * - Notes availability check (unfetched → incomplete) * @@ -245,7 +298,11 @@ export const verifyCaptureRecords = (opts: VerifyCaptureOptions): VerifyCaptureR persist(result); return result; } - const { activeRecordIds, activeCanonicalTuples } = history; + // Do not mutate a caller-provided historical snapshot: shadow reuses one + // across many verification calls. This local reservation set also keeps + // identities distinct when a permissive policy permits several records. + const reservedRecordIds = new Set(history.recordIds); + const { activeCanonicalTuples } = history; // 4. Delegate to verifyDraft for evidence/grammar checking const verifyResult = verifyDraft(draft, { transcript, diff }); @@ -255,11 +312,11 @@ export const verifyCaptureRecords = (opts: VerifyCaptureOptions): VerifyCaptureR const id = recordIdOf(verified.record); // Check duplicate Record-Id - if (id && activeRecordIds.has(id)) { + if (id && reservedRecordIds.has(id)) { rejected.push({ record: verified.record, reason: 'duplicate-record-id', - detail: `Record-Id "${id}" already exists in active records`, + detail: `Record-Id "${id}" already exists in repository history`, }); continue; } @@ -276,6 +333,7 @@ export const verifyCaptureRecords = (opts: VerifyCaptureOptions): VerifyCaptureR } accepted.push(verified); + if (id) reservedRecordIds.add(id); } // ADR-0030. In `auto` the host stages without asking, so nobody read this @@ -296,6 +354,18 @@ export const verifyCaptureRecords = (opts: VerifyCaptureOptions): VerifyCaptureR } } + // The only safe place to mint is after every evidence, vocabulary, and + // duplicate-content check above. A rejected draft remains exactly the + // discarded proposal it arrived as; it never consumes or reveals an id. + // This is intentionally beside provenance stamping: both are facts the + // unattended pipeline establishes about a record it has accepted. + for (const verified of accepted) { + if (recordIdOf(verified.record) !== undefined) continue; + const id = mintRecordId(verified.record, reservedRecordIds); + verified.record.trailers = [...verified.record.trailers, { key: 'Record-Id', value: id }]; + reservedRecordIds.add(id); + } + // Collect rejections from verifyDraft for (const rejectedRec of verifyResult.rejected) { rejected.push({ diff --git a/test/capture-verify.test.ts b/test/capture-verify.test.ts index 273127b7..9d5727c4 100644 --- a/test/capture-verify.test.ts +++ b/test/capture-verify.test.ts @@ -72,6 +72,22 @@ const validDraft = (quote: string): DraftRecord => ({ ], }); +/** A valid draft that relies on the capture pipeline to supply its identity. */ +const validDraftWithoutRecordId = (quote: string): DraftRecord => ({ + trailers: [{ key: 'Limit', value: 'Do not use shared mutable state for config' }], + evidence: [ + { + key: 'Limit', + source: 'transcript', + quote, + locator: 'L1-L2', + }, + ], +}); + +const recordId = (record: DraftRecord): string | undefined => + record.trailers.find((trailer) => trailer.key === 'Record-Id')?.value; + /** A draft record whose quote does NOT exist in the transcript (fabricated). */ const fabricatedDraft = (): DraftRecord => ({ trailers: [ @@ -141,6 +157,103 @@ describe('verifyCaptureRecords', () => { expect(result.validation_result).toBe('pass'); }); + it('mints a grammar-valid Record-Id for an accepted draft that omitted one', () => { + const transcript = 'We decided: Do not use shared mutable state for config because it causes race conditions.'; + const diff = ''; + const nonce = prepare(cwd, transcript, diff); + + const result = verifyCaptureRecords({ + nonce, + draft: [validDraftWithoutRecordId('Do not use shared mutable state for config because it causes race conditions')], + transcript, + diff, + cwd, + }); + + expect(result.accepted).toHaveLength(1); + expect(recordId(result.accepted[0]!.record)).toMatch(/^r-[a-z0-9]{6,}$/); + }); + + it('mints the same Record-Id when an unchanged draft is prepared again', () => { + const transcript = 'We decided: Do not use shared mutable state for config because it causes race conditions.'; + const diff = ''; + const quote = 'Do not use shared mutable state for config because it causes race conditions'; + + const first = verifyCaptureRecords({ + nonce: prepare(cwd, transcript, diff), + draft: [validDraftWithoutRecordId(quote)], + transcript, + diff, + cwd, + }); + const second = verifyCaptureRecords({ + nonce: prepare(cwd, transcript, diff), + draft: [validDraftWithoutRecordId(quote)], + transcript, + diff, + cwd, + }); + + expect(recordId(first.accepted[0]!.record)).toBe(recordId(second.accepted[0]!.record)); + }); + + it('preserves a Record-Id supplied by an accepted draft', () => { + const transcript = 'We decided: Do not use shared mutable state for config because it causes race conditions.'; + const diff = ''; + const nonce = prepare(cwd, transcript, diff); + + const result = verifyCaptureRecords({ + nonce, + draft: [validDraft('Do not use shared mutable state for config because it causes race conditions')], + transcript, + diff, + cwd, + }); + + expect(recordId(result.accepted[0]!.record)).toBe('r-test123abc'); + }); + + it('deterministically probes past an identity already present in history', () => { + const transcript = 'We decided: Do not use shared mutable state for config because it causes race conditions.'; + const diff = ''; + const quote = 'Do not use shared mutable state for config because it causes race conditions'; + const first = verifyCaptureRecords({ + nonce: prepare(cwd, transcript, diff), + draft: [validDraftWithoutRecordId(quote)], + transcript, + diff, + cwd, + }); + const collidingId = recordId(first.accepted[0]!.record); + + writeFileSync(join(cwd, '.record-message'), `Reserve an identity\n\nLimit: unrelated historical record\nRecord-Id: ${collidingId}\n`); + execSync('git commit --allow-empty -F .record-message', { cwd, stdio: 'ignore' }); + + const second = verifyCaptureRecords({ + nonce: prepare(cwd, transcript, diff), + draft: [validDraftWithoutRecordId(quote)], + transcript, + diff, + cwd, + }); + + expect(second.accepted).toHaveLength(1); + expect(recordId(second.accepted[0]!.record)).not.toBe(collidingId); + expect(recordId(second.accepted[0]!.record)).toMatch(/^r-[a-z0-9]{6,}$/); + }); + + it('does not mint an identity for a rejected draft', () => { + const transcript = 'Normal conversation about nothing.'; + const diff = ''; + const nonce = prepare(cwd, transcript, diff); + const rejected = validDraftWithoutRecordId('This sentence was never said by anyone in any conversation'); + + const result = verifyCaptureRecords({ nonce, draft: [rejected], transcript, diff, cwd }); + + expect(result.accepted).toHaveLength(0); + expect(recordId(rejected)).toBeUndefined(); + }); + // === Security property: all rejected → empty, never throws === it('all fabricated → empty', () => { const transcript = 'Normal conversation about nothing.'; diff --git a/test/gate-a-e2e.test.ts b/test/gate-a-e2e.test.ts index 4e51cc68..f6c6010b 100644 --- a/test/gate-a-e2e.test.ts +++ b/test/gate-a-e2e.test.ts @@ -184,12 +184,12 @@ const runGit = (cwd: string, args: string[]): { stdout: string; stderr: string; const TRANSCRIPT_CONTENT = 'The team decided to use SQLite instead of PostgreSQL for local storage.'; /** Create a valid draft JSON that will pass verification against TRANSCRIPT_CONTENT. */ -const makeValidDraft = (recordId: string): object => ({ +const makeValidDraft = (recordId?: string): object => ({ records: [ { trailers: [ { key: 'Ruled-out', value: 'PostgreSQL | SQLite chosen for local storage simplicity' }, - { key: 'Record-Id', value: recordId }, + ...(recordId === undefined ? [] : [{ key: 'Record-Id', value: recordId }]), ], evidence: [ { @@ -206,7 +206,7 @@ const makeValidDraft = (recordId: string): object => ({ /** Run the full CLI capture pipeline: write files, invoke capture command. */ const runCapturePipeline = ( cwd: string, - recordId: string, + recordId?: string, ): { nonce: string | null; staged: boolean; stderr: string } => { const transcriptPath = join(cwd, '.commitlore-transcript.tmp'); const draftPath = join(cwd, '.commitlore-draft.tmp'); @@ -371,7 +371,7 @@ describe('Scenario 1: CLI capture full chain', () => { runGit(repo, ['add', 'feature.ts']); // Run capture pipeline - const capture = runCapturePipeline(repo, 'r-e2escenario1'); + const capture = runCapturePipeline(repo); expect(capture.staged, 'capture must stage successfully').toBe(true); expect(capture.nonce, 'nonce must be returned').toMatch(/^[0-9a-f]{32}$/); @@ -379,9 +379,11 @@ describe('Scenario 1: CLI capture full chain', () => { const commitResult = runGit(repo, ['commit', '-m', 'feat: add feature']); expect(commitResult.status, `git commit failed: ${commitResult.stderr}`).toBe(0); - // Verify the commit message contains our Record-Id + // The draft omitted Record-Id, so the complete capture path must mint one + // before the ordinary Git commit applies its pending record. const logResult = runGit(repo, ['log', '-1', '--format=%B']); - expect(logResult.stdout).toContain('Record-Id: r-e2escenario1'); + const minted = /^Record-Id: (r-[a-z0-9]{6,})$/m.exec(logResult.stdout)?.[1]; + expect(minted).toMatch(/^r-[a-z0-9]{6,}$/); // Verify the pending file was consumed const pendingFiles = readPendingFiles(repo); @@ -394,7 +396,7 @@ describe('Scenario 1: CLI capture full chain', () => { // Verify record is queryable via CLI context const queryResult = runCli(repo, ['context', '--json']); - expect(queryResult.stdout).toContain('r-e2escenario1'); + expect(queryResult.stdout).toContain(minted); }); });