Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | 1x 1x 1x 9x 9x 32x 6x 3x 1x 8x 25x 5x 3x 11x 1x 2x | /**
* memory-policy.ts
*
* Pure validation functions for attempt-history writes and gap-summary injections.
* Enforces two rules:
* 1. Writes must not contain language that softens or overrides grading.
* 2. Injected summaries must not frame gaps as personal failure.
*/
export interface PolicyResult {
allowed: boolean;
reason?: string;
}
// Phrases that soften criticism or attempt to override rubric grading
const SOFTENING_PATTERNS: RegExp[] = [
/\bignore\s+(this|the)\s+(issue|gap|problem|error)\b/i,
/\bdon'?t\s+penali[sz]e\b/i,
/\bgive\s+(full|partial)\s+credit\s+anyway\b/i,
/\boverride\s+(the\s+)?rubric\b/i,
/\bmark\s+(it|this)\s+as\s+(correct|passing|full)\b/i,
];
// Phrases that frame gaps as personal failure (not allowed in injected context)
const PERSONAL_FAILURE_PATTERNS: RegExp[] = [
/\byou\s+(always|never|keep)\s+(fail|mess|get\s+wrong)\b/i,
/\byou'?re?\s+(bad|terrible|hopeless)\s+at\b/i,
/\byou\s+clearly\s+don'?t\s+understand\b/i,
/\byou\s+struggle\s+with\b/i,
];
/**
* Validates an AttemptRecord before writing it to history.
* Rejects records whose gap text contains grading-softening language.
*/
export function validateWrite(record: { gaps?: string[] }): PolicyResult {
const text = (record.gaps ?? []).join(" ");
for (const pattern of SOFTENING_PATTERNS) {
if (pattern.test(text)) {
return {
allowed: false,
reason: `Gap text contains softening language matching: ${pattern.source}`,
};
}
}
return { allowed: true };
}
/**
* Validates a gap summary string before injecting it into the model context.
* Rejects summaries that soften grading or frame gaps as personal failure.
*/
export function validateInject(summary: string): PolicyResult {
for (const pattern of PERSONAL_FAILURE_PATTERNS) {
if (pattern.test(summary)) {
return {
allowed: false,
reason: `Summary uses personal failure framing matching: ${pattern.source}`,
};
}
}
for (const pattern of SOFTENING_PATTERNS) {
if (pattern.test(summary)) {
return {
allowed: false,
reason: `Summary contains softening language matching: ${pattern.source}`,
};
}
}
return { allowed: true };
}
|