B2: read approved stale-fill decisions from more valid ledger records

The structured ledger reader is authoritative before the prose fallback,
but it missed two valid approved records in passing censuses
(37186854666: a camelCase writeProfile subject; 37195203538: a
slash-joined 'D1 / STALE-FILL' row id), which then rested on the prose
detector that caused both historical reds. Both forms are accepted; an
unresolved row, an unrelated decision, the copied fixture plan and
non-write camelCase words stay refused.
This commit is contained in:
garrytan committed 2026-10-04 17:58:20 +00:00
1 parent aef2113243
commit 727e443026
2 files changed
+39 -3

No files matched your search

+31
View File
@@ -55,3 +55,34 @@ describe('CEO stale-fill decision from the skill-defined ledger and currentDecis
expect(hasApprovedStaleFillDecision('```text\n' + report.replaceAll('```', '') + '\n```')).toBe(false);
});
});
describe('structured reader alone on the plan-ceo-section-loading corpus', () => {
const corpus = path.join(import.meta.dir, 'fixtures', 'detector-corpora', 'plan-ceo-section-loading');
const entry = (name: string): string => JSON.parse(fs.readFileSync(path.join(corpus, name), 'utf8')).input.report;
const camelWrite = entry('37186854666-t1-pass.json');
const camelQuestion = camelWrite.split('\n').find(line => line.startsWith('Question: D1'))!;
test('reads an approved decision whose question names the write as writeProfile (37186854666)', () => {
expect(camelQuestion).toContain('writeProfile');
expect(hasApprovedStaleFillDecision(camelWrite)).toBe(true);
});
test('reads an approved decision under the slash-joined row ID D1 / STALE-FILL (37195203538)', () => {
expect(hasApprovedStaleFillDecision(entry('37195203538-t1-pass.json'))).toBe(true);
});
test('still refuses an unrelated decision, the copied plan and an unresolved ledger row', () => {
expect(hasApprovedStaleFillDecision(entry('37182865432-t1-fail-derived-unrelated-decision.json'))).toBe(false);
expect(hasApprovedStaleFillDecision(CEO_SECTION_CACHE_PLAN)).toBe(false);
expect(hasApprovedStaleFillDecision(entry('37174266054-t1-pass.json'))).toBe(false);
});
test.each(['rewriteProfile', 'isWriteable', 'writeable'])('a question whose only write term is %s is not the race', identifier => {
expect(hasApprovedStaleFillDecision(camelWrite.replace(camelQuestion, camelQuestion.replace('writeProfile', identifier)))).toBe(false);
});
test('a slash-joined ID still needs its own approved ledger row', () => {
const report = entry('37195203538-t1-pass.json');
expect(hasApprovedStaleFillDecision(report.replaceAll('| D1 / STALE-FILL ', '| D1 / OTHER-ROW '))).toBe(false);
});
});
+8 -3
View File
@@ -12,6 +12,11 @@
const LEDGER_HEADER = /^\|\s*ID and owner\s*\|\s*Contract and evidence\s*\|\s*Current\s*\|\s*Proposed\s*\|\s*Status\s*\|\s*Exact approval and scope\s*\|\s*$/;
const FILL = /\b(?:fill\w*|refill\w*|repopulat\w*)\b|\bcache\.set\b/i;
const WRITE = /\b(?:writes?|written|writer|commit\w*)\b/i;
const CAMEL_WRITE = /\b[wW]rite[A-Z]\w*/;
const ROW_ID = String.raw`[A-Za-z][\w-]*(?:\s*\/\s*[A-Za-z][\w-]*)*`;
const ROW_ID_CELL = new RegExp(String.raw`^(${ROW_ID})(?=\s|$)`);
const DECISION_HEADING = new RegExp(String.raw`^#{2,3}\s+currentDecision \((${ROW_ID})\)\s*$`);
const normalizeId = (id: string | undefined) => id?.replace(/\s*\/\s*/g, '/');
const RACE = /\b(?:stale|race|racing|overwrit\w*|newer|old|older|before|after|overlap\w*|in[- ]flight|concurrent\w*)\b/i;
/** Asserted lines only: fenced blocks, block quotes and indented code become blank. */
@@ -36,7 +41,7 @@ function ledgerRows(lines: string[]): Map<string, string> {
if (!LEDGER_HEADER.test(lines[i]!)) continue;
for (let j = i + 2; j < lines.length && lines[j]!.trimStart().startsWith('|'); j++) {
const cells = lines[j]!.trim().slice(1, -1).split('|').map(cell => cell.trim());
const id = /^([A-Za-z][\w-]*)(?=\s|$)/.exec(cells[0] ?? '')?.[1];
const id = normalizeId(ROW_ID_CELL.exec(cells[0] ?? '')?.[1]);
// A row that does not split into the six ledger cells is not a record.
if (!id || cells.length !== 6) continue;
rows.set(id, cells[4]!);
@@ -50,12 +55,12 @@ export function hasApprovedStaleFillDecision(report: string): boolean {
const lines = proseLines(report);
const rows = ledgerRows(lines);
for (let i = 0; i < lines.length; i++) {
const rowId = /^#{2,3}\s+currentDecision \(([A-Za-z][\w-]*)\)\s*$/.exec(lines[i]!)?.[1];
const rowId = normalizeId(DECISION_HEADING.exec(lines[i]!)?.[1]);
if (!rowId) continue;
for (let j = i + 1; j < lines.length && !/^#{1,6}\s/.test(lines[j]!); j++) {
const subject = /^Question:\s*D[1-9]\d*\s*[—–-]\s*(.+)$/.exec(lines[j]!)?.[1];
if (!subject) continue;
if (FILL.test(subject) && WRITE.test(subject) && RACE.test(subject) && /^[*_]*approved\b/i.test(rows.get(rowId) ?? '')) return true;
if (FILL.test(subject) && (WRITE.test(subject) || CAMEL_WRITE.test(subject)) && RACE.test(subject) && /^[*_]*approved\b/i.test(rows.get(rowId) ?? '')) return true;
break;
}
}