Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/cli/run-completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@ export interface RunCompletionTracker {
* O101 layer 3: protected paths modified by a shell command (post-run
* detection). When set, the run is incomplete regardless of model claims.
*/
protectedPathChanges?: Array<{ path: string; kind: string; command?: string }>;
protectedPathChanges?: Array<{
path: string;
kind: string;
command?: string;
keys?: string[];
reason?: string;
}>;
/**
* O103: protected-path writes the approval gate refused before they ran
* (`-p` deny or user said no). Drives the outcome on its own — a run with a
Expand Down Expand Up @@ -453,15 +459,21 @@ export function noteBackgroundProtectedPathMods(tracker: RunCompletionTracker):
if (!changes || changes.length === 0) continue;
mergeProtectedPathChanges(
tracker,
changes.map((c) => ({ path: c.path, kind: c.kind, command: snap.command })),
changes.map((c) => ({ ...c, keys: c.keys ? [...c.keys] : undefined, command: snap.command })),
`exec_background: ${snap.command.replace(/\s+/g, ' ').trim().slice(0, 120)}`
);
}
}

function mergeProtectedPathChanges(
tracker: RunCompletionTracker,
additions: Array<{ path: string; kind: string; command?: string }>,
additions: Array<{
path: string;
kind: string;
command?: string;
keys?: string[];
reason?: string;
}>,
failedStep?: string
): void {
if (additions.length === 0) return;
Expand Down
7 changes: 6 additions & 1 deletion src/cli/run-outcome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ import {
type SafetyBlock,
type VerificationCheck,
} from './run-completion.js';
import { protectedPathModReason } from '../safety/protected-path-snapshot.js';
import {
protectedPathModReason,
type GitConfigChangeReason,
} from '../safety/protected-path-snapshot.js';
import { hookEventZhName } from './hook-event-names.js';

export type { GoalVerifyResult, RunCompletionTracker, VerificationCheck };
Expand Down Expand Up @@ -177,6 +180,8 @@ export function resolveRunOutcome(input: ResolveRunOutcomeInput): RunOutcome {
mods.map((m) => ({
path: m.path,
kind: (m.kind as 'added' | 'modified' | 'deleted') || 'modified',
...(m.keys ? { keys: m.keys } : {}),
...(m.reason ? { reason: m.reason as GitConfigChangeReason } : {}),
})),
mods[0]?.command
);
Expand Down
9 changes: 7 additions & 2 deletions src/core/tools/background-process-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ export interface BackgroundProcSnapshot {
* O108: protected-path changes detected by layer-3 snapshot when this
* process fully exited (metadata only — never file contents).
*/
protectedPathChanges?: ReadonlyArray<{ path: string; kind: string }>;
protectedPathChanges?: ReadonlyArray<{
path: string;
kind: string;
keys?: string[];
reason?: string;
}>;
}

export interface BackgroundOutputChunk {
Expand Down Expand Up @@ -80,7 +85,7 @@ export interface BackgroundProc {
* O108: set on full exit when layer-3 snapshot detects protected-path
* modifications (paths + kind only).
*/
protectedPathChanges?: Array<{ path: string; kind: string }>;
protectedPathChanges?: Array<{ path: string; kind: string; keys?: string[]; reason?: string }>;

killTimer?: ReturnType<typeof setTimeout>;
killRequested?: boolean;
Expand Down
Loading
Loading