osborn 0.9.234 → 0.9.235
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/claude-llm.js +37 -0
- package/package.json +1 -1
package/dist/claude-llm.js
CHANGED
|
@@ -95,6 +95,15 @@ async function buildRecallInjection(sessionId, workingDir, prompt) {
|
|
|
95
95
|
// agent's direct tool calls count against the budget.
|
|
96
96
|
let turnToolCallCount = 0;
|
|
97
97
|
const TOOL_CALL_BUDGET = 5;
|
|
98
|
+
// Writer PROVENANCE REMINDER (Chesterton's Fence): before the writer mutates a
|
|
99
|
+
// version-controlled file it should review that file's git history so the edit is
|
|
100
|
+
// backward-informed (root cause / prior + reverted attempts / cross-component coupling),
|
|
101
|
+
// not forward-only. Delivered as a ONE-SHOT PreToolUse deny-with-reminder on the writer's
|
|
102
|
+
// first edit of an existing file each turn. This single flag is the irreducible minimum:
|
|
103
|
+
// a PreToolUse hook can only allow/deny/ask (no "inject note + proceed"), so the reminder
|
|
104
|
+
// must be a deny — and without a "already nudged this turn" flag that deny would loop
|
|
105
|
+
// forever. Reset on every UserPromptSubmit (new turn).
|
|
106
|
+
let writerHistoryReminded = false;
|
|
98
107
|
/**
|
|
99
108
|
* Strip markdown formatting for TTS (text-to-speech)
|
|
100
109
|
* Removes **bold**, ##headers, ```code```, etc. so TTS doesn't read them literally
|
|
@@ -493,6 +502,13 @@ export const NAMED_AGENTS = {
|
|
|
493
502
|
'4. If ANYTHING has drifted from the plan (file moved, code refactored, dependency changed):',
|
|
494
503
|
' STOP and report back to the main agent. Do NOT improvise.',
|
|
495
504
|
'',
|
|
505
|
+
'### Step 1b: Review history before touching a versioned file',
|
|
506
|
+
'For any file that ALREADY EXISTS (i.e. has git history), review its lineage BEFORE you edit it (on your first edit of an existing file each turn you\'ll get a one-time reminder to). This is Chesterton\'s Fence — understand WHY the code is there before you change it. Do:',
|
|
507
|
+
' 1. `git log --follow -p -- "<file>"` — recent commits and the rationale behind them.',
|
|
508
|
+
' 2. `git blame` on the exact lines you will change — who/when/which commit introduced them.',
|
|
509
|
+
' 3. `git log --oneline --grep=<feature>` and `git log --oneline -S"<symbol>"` — look for related OR REVERTED work so you do not redo something already tried, and note which components were co-changed (coupling).',
|
|
510
|
+
'Fix problems backward-informed — root cause, systemic implications, prior attempts — not forward-only. New files are exempt (no history to review).',
|
|
511
|
+
'',
|
|
496
512
|
'### Step 2: Clarify unknowns',
|
|
497
513
|
'1. If the plan is vague or ambiguous — ask the main agent a specific clarifying question.',
|
|
498
514
|
' Examples: "Which config format — YAML or JSON?", "New file or extend existing auth.ts?"',
|
|
@@ -1873,6 +1889,25 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
1873
1889
|
// hardcoded per-role branches had, now in one visible place.
|
|
1874
1890
|
if (toolName === 'Write' || toolName === 'Edit' || toolName === 'MultiEdit') {
|
|
1875
1891
|
const filePath = String(toolInput.file_path || '');
|
|
1892
|
+
// Writer PROVENANCE REMINDER (Chesterton's Fence): on the writer's FIRST edit of
|
|
1893
|
+
// an EXISTING (version-controlled) file this turn, deny ONCE with a reminder to
|
|
1894
|
+
// review the file's git history so the change is backward-informed (root cause,
|
|
1895
|
+
// prior/reverted attempts, cross-component coupling), not forward-only — then it
|
|
1896
|
+
// proceeds. New files are exempt (no history). One-shot per turn so it can't loop.
|
|
1897
|
+
if (agentType === 'writer' && filePath && existsSync(filePath) && !writerHistoryReminded) {
|
|
1898
|
+
writerHistoryReminded = true;
|
|
1899
|
+
const base = filePath.split('/').pop() || filePath;
|
|
1900
|
+
const gateReason = [
|
|
1901
|
+
`Before editing ${base}, first review its history so your change is backward-informed, not forward-only (Chesterton's Fence — understand WHY this code exists before changing it):`,
|
|
1902
|
+
` 1. git log --follow -p -- "${filePath}" (recent commits + rationale)`,
|
|
1903
|
+
` 2. git blame the specific lines you're about to change (who/when/which commit)`,
|
|
1904
|
+
` 3. git log --oneline --grep=<feature> and git log --oneline -S"<symbol>" (related OR reverted work so you don't redo something already tried; note components co-changed in those commits)`,
|
|
1905
|
+
`Then re-attempt this edit. (One-time reminder this turn; new files are exempt.)`,
|
|
1906
|
+
].join('\n');
|
|
1907
|
+
console.log(`🏛️ Writer provenance reminder: nudging before ${base} (first edit of an existing file this turn)`);
|
|
1908
|
+
this.#eventEmitter.emit('tool_blocked', { name: toolName, reason: `Review ${base}'s git history first (one-time provenance reminder).` });
|
|
1909
|
+
return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny' }, reason: gateReason };
|
|
1910
|
+
}
|
|
1876
1911
|
const { decision, reason } = decideWrite(agentType, filePath);
|
|
1877
1912
|
console.log(`🔎 Write gate: agent=${agentType ?? 'main'} path="${filePath || '(none)'}" → ${decision}`);
|
|
1878
1913
|
if (decision === 'deny') {
|
|
@@ -1944,6 +1979,8 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
1944
1979
|
try {
|
|
1945
1980
|
// Reset the per-turn tool call counter so the new turn starts fresh.
|
|
1946
1981
|
turnToolCallCount = 0;
|
|
1982
|
+
// Reset the writer provenance-reminder flag for the new turn.
|
|
1983
|
+
writerHistoryReminded = false;
|
|
1947
1984
|
const reminder = readFileSync(TURN_SHAPE_REMINDER_PATH, 'utf-8');
|
|
1948
1985
|
const promptPreview = String(input?.prompt || '').substring(0, 60).replace(/\n/g, ' ');
|
|
1949
1986
|
// Reliable recall: retrieve prior messages relevant to THIS prompt and inject
|