@bjoernrochel/sevro 0.1.0-rc.8 → 1.0.0
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/CONTRIBUTING.md +22 -6
- package/README.md +5 -1
- package/docs/README.md +19 -15
- package/docs/architecture.md +138 -17
- package/docs/assets/README.md +5 -4
- package/docs/builtin-graders-v1.md +9 -2
- package/docs/codex-host.md +155 -57
- package/docs/contracts.md +2 -1
- package/docs/creating-cases.md +9 -2
- package/docs/development-cli.md +187 -19
- package/docs/documentation-quality.md +12 -2
- package/docs/evaluation-workflow.md +110 -0
- package/docs/extension-protocol-v1.md +26 -3
- package/docs/getting-started.md +23 -2
- package/docs/guide-evaluation.md +33 -1
- package/docs/identity-v1.md +25 -2
- package/docs/installing.md +11 -11
- package/docs/native-controls.md +76 -5
- package/docs/native-hosts.md +196 -7
- package/docs/reading-results.md +102 -0
- package/docs/recipes.md +489 -0
- package/docs/releases.md +31 -12
- package/docs/report-v1.md +29 -1
- package/docs/results-v1.md +122 -4
- package/docs/run-settings-v1.md +147 -0
- package/docs/runtime-v1.md +255 -22
- package/docs/troubleshooting.md +12 -12
- package/docs/typescript-quality.md +89 -26
- package/examples/recipes/candidate.ts +26 -0
- package/examples/recipes/cases/coding-change.json +21 -0
- package/examples/recipes/cases/host-tools.json +21 -0
- package/examples/recipes/cases/mise.json +21 -0
- package/examples/recipes/cases/node.json +21 -0
- package/examples/recipes/cases/python-uv.json +21 -0
- package/examples/recipes/cases/semantic.json +17 -0
- package/examples/recipes/coding-change/check.ts +23 -0
- package/examples/recipes/extension-artifacts.ts +65 -0
- package/examples/recipes/extension-methods.ts +174 -0
- package/examples/recipes/extension.ts +37 -0
- package/examples/recipes/repository-skill/.agents/skills/startup-guide/SKILL.md +7 -0
- package/examples/recipes/repository-skill/.claude/skills/startup-guide/SKILL.md +7 -0
- package/examples/recipes/repository-skill/README.md +3 -0
- package/examples/recipes/run-inputs.ts +188 -0
- package/examples/recipes/run-options.ts +131 -0
- package/examples/recipes/run.ts +63 -0
- package/examples/recipes/runtime/empty.json +1 -0
- package/examples/recipes/runtime/goals.json +1 -0
- package/examples/recipes/runtime/mise.json +6 -0
- package/examples/recipes/runtime/path.json +1 -0
- package/examples/recipes/runtime/plugins.json +4 -0
- package/examples/recipes/runtime/python-uv.json +10 -0
- package/examples/recipes/semantic-judge.ts +29 -0
- package/examples/templates/coding/adapter.ts +17 -0
- package/examples/templates/coding/case.json +15 -0
- package/examples/templates/repository-skill/.agents/skills/startup-guide/SKILL.md +6 -0
- package/examples/templates/repository-skill/extension-data.ts +64 -0
- package/examples/templates/repository-skill/extension.ts +31 -0
- package/examples/templates/response/adapter.ts +12 -0
- package/examples/templates/response/case.json +13 -0
- package/package.json +11 -5
- package/schemas/report-v1.schema.json +9 -0
- package/schemas/run-evidence-v1.schema.json +2 -1
- package/schemas/runtime-v1.schema.json +43 -7
- package/src/advisory.ts +2 -2
- package/src/candidate-artifacts.ts +42 -11
- package/src/candidate-codex-state.ts +185 -0
- package/src/case-validation.ts +73 -50
- package/src/cli/cancellation.ts +20 -0
- package/src/cli/command.ts +87 -0
- package/src/cli/completion.ts +15 -0
- package/src/cli/demo.ts +60 -0
- package/src/cli/evaluation.ts +55 -0
- package/src/cli/extension.ts +79 -0
- package/src/cli/help.ts +198 -0
- package/src/cli/hosts.ts +55 -0
- package/src/cli/init-settings.ts +30 -0
- package/src/cli/init.ts +111 -0
- package/src/{cli-invocation.ts → cli/invocation.ts} +214 -218
- package/src/cli/loading.ts +151 -0
- package/src/cli/preparation.ts +154 -0
- package/src/cli/presentation.ts +93 -0
- package/src/cli/progress.ts +6 -0
- package/src/cli/run-manifest.ts +128 -0
- package/src/cli/run-options.ts +403 -0
- package/src/cli/run-overrides.ts +69 -0
- package/src/cli/settings.ts +154 -0
- package/src/cli/summary.ts +43 -0
- package/src/cli.ts +13 -591
- package/src/contract-types.ts +94 -0
- package/src/engine.ts +9 -5
- package/src/evaluation/advisory.ts +150 -0
- package/src/{evaluation-check-plan.ts → evaluation/check-plan.ts} +103 -67
- package/src/evaluation/collection.ts +88 -0
- package/src/evaluation/context.ts +10 -0
- package/src/{evaluation-grading-host.ts → evaluation/grading-host.ts} +5 -5
- package/src/evaluation/grading.ts +235 -0
- package/src/{evaluation-invocation-plan.ts → evaluation/invocation-plan.ts} +147 -58
- package/src/{evaluation-plan.ts → evaluation/plan.ts} +208 -141
- package/src/evaluation/progress.ts +19 -0
- package/src/evaluation/resources.ts +241 -0
- package/src/evaluation/run.ts +206 -0
- package/src/{evaluation-semantic.ts → evaluation/semantic.ts} +77 -87
- package/src/evaluation/trial.ts +800 -0
- package/src/{evaluation-types.ts → evaluation/types.ts} +79 -29
- package/src/evidence/host-results.ts +85 -0
- package/src/evidence/retained-artifacts.ts +18 -0
- package/src/evidence/trial-writer.ts +203 -0
- package/src/evidence/usage.ts +17 -0
- package/src/extension-client.ts +34 -96
- package/src/extension-session.ts +24 -48
- package/src/{advisory-fixture.ts → fixtures/advisory.ts} +12 -72
- package/src/{fixture-bin.ts → fixtures/bin.ts} +1 -1
- package/src/{fixture-cleanup.ts → fixtures/cleanup.ts} +13 -7
- package/src/fixtures/create.ts +183 -0
- package/src/{generated-fixture.ts → fixtures/generated.ts} +10 -53
- package/src/{git-hooks.ts → fixtures/git-hooks.ts} +1 -1
- package/src/{preparation.ts → fixtures/preparation.ts} +6 -16
- package/src/{repository-fixture.ts → fixtures/repository.ts} +30 -64
- package/src/{fixture-setup.ts → fixtures/setup.ts} +33 -51
- package/src/{fixture-tools.ts → fixtures/tools.ts} +1 -1
- package/src/{workspace-state.ts → fixtures/workspace-state.ts} +5 -5
- package/src/generated/cli-result.d.cts +2 -1
- package/src/generated/extension.d.cts +2 -1
- package/src/generated/report.cjs +1 -1
- package/src/generated/report.d.cts +2 -1
- package/src/generated/run-evidence.cjs +1 -1
- package/src/generated/run-evidence.d.cts +2 -1
- package/src/generated/runtime.cjs +1 -1
- package/src/generated/runtime.d.cts +2 -1
- package/src/git.ts +93 -0
- package/src/graders/git-head.ts +29 -84
- package/src/graders/shell.ts +50 -68
- package/src/host-diagnostic-redaction.ts +52 -0
- package/src/host-diagnostics.ts +331 -0
- package/src/hosts/claude-continuation.ts +57 -40
- package/src/hosts/claude-credential.ts +160 -63
- package/src/hosts/claude-events.ts +34 -18
- package/src/hosts/claude-keychain.ts +78 -21
- package/src/hosts/claude-login-recovery.ts +85 -0
- package/src/hosts/claude-login-refresh.ts +178 -0
- package/src/hosts/claude-login-store.ts +162 -0
- package/src/hosts/claude-login.ts +107 -0
- package/src/hosts/claude-native-goal.ts +15 -12
- package/src/hosts/claude-process.ts +10 -50
- package/src/hosts/claude-refresh-lock.ts +81 -0
- package/src/hosts/claude-repository-invocation.ts +9 -34
- package/src/hosts/claude-settings.ts +46 -9
- package/src/hosts/claude-skill-activations.ts +169 -0
- package/src/hosts/claude-state.ts +28 -15
- package/src/hosts/claude-tool-calls.ts +13 -10
- package/src/hosts/claude.ts +121 -81
- package/src/hosts/codex-app-server.ts +78 -52
- package/src/hosts/codex-configuration.ts +5 -10
- package/src/hosts/codex-exec-controls.ts +516 -0
- package/src/hosts/codex-marketplace.ts +12 -10
- package/src/hosts/codex-native-calls.ts +15 -122
- package/src/hosts/codex-process.ts +10 -183
- package/src/hosts/codex-profile.ts +36 -21
- package/src/hosts/codex-session-files.ts +1 -9
- package/src/hosts/codex-state.ts +134 -18
- package/src/hosts/codex.ts +210 -183
- package/src/hosts/isolation-common.ts +8 -11
- package/src/hosts/isolation-roots.ts +2 -2
- package/src/hosts/linux-sandbox.ts +15 -2
- package/src/hosts/mac-sandbox.ts +87 -18
- package/src/hosts/native-controls.ts +72 -22
- package/src/hosts/native-request.ts +55 -0
- package/src/hosts/process-lifecycle.ts +216 -48
- package/src/hosts/protected-worktrees.ts +1 -1
- package/src/hosts/skill-hook-catalog.ts +131 -0
- package/src/hosts/skill-hook-handler.ts +374 -0
- package/src/hosts/skill-hooks.ts +577 -0
- package/src/instrumentation.ts +7 -8
- package/src/native-transcript-state.ts +22 -3
- package/src/native-transcript-view.ts +52 -13
- package/src/native-transcripts.ts +26 -11
- package/src/paths.ts +22 -0
- package/src/process-lifecycle.ts +150 -0
- package/src/provenance.ts +27 -7
- package/src/prune.ts +300 -0
- package/src/report.ts +63 -36
- package/src/resolved-case.ts +1 -1
- package/src/results-lock.ts +42 -0
- package/src/results.ts +14 -18
- package/src/{runtime-config.ts → runtime/config.ts} +160 -46
- package/src/{runtime-discovery-apple.ts → runtime/discovery-apple.ts} +3 -3
- package/src/{runtime-discovery-providers.ts → runtime/discovery-providers.ts} +3 -9
- package/src/{runtime-discovery.ts → runtime/discovery.ts} +4 -4
- package/src/{runtime-hook-processes.ts → runtime/hook-processes.ts} +1 -1
- package/src/{runtime-hooks.ts → runtime/hooks.ts} +32 -22
- package/src/{runtime-paths.ts → runtime/paths.ts} +5 -19
- package/src/{runtime-query.ts → runtime/query.ts} +5 -5
- package/src/{runtime-seeds.ts → runtime/seeds.ts} +3 -3
- package/src/runtime/shared-cache.ts +130 -0
- package/src/{runtime-state.ts → runtime/state.ts} +28 -11
- package/src/schema-types.ts +73 -161
- package/src/shell.ts +4 -0
- package/src/transcript-retention.ts +146 -0
- package/src/value-guards.ts +22 -0
- package/docs/assets/sevro-logo.png +0 -0
- package/docs/assets/sevro-symbol.svg +0 -1
- package/docs/assets/sevro-wordmark.svg +0 -1
- package/docs/cache-ownership-validation.md +0 -49
- package/docs/claude-continuation-validation.md +0 -47
- package/docs/concurrency-validation.md +0 -86
- package/docs/configuration-root-validation.md +0 -70
- package/docs/engine-slice.md +0 -114
- package/docs/evidence/runtime-startup-30/README.md +0 -185
- package/docs/evidence/runtime-startup-30/after.json +0 -319
- package/docs/evidence/runtime-startup-30/baseline-timeout.jsonl +0 -2
- package/docs/evidence/runtime-startup-30/before.json +0 -403
- package/docs/evidence/runtime-startup-30/consumer-smoke.json +0 -63
- package/docs/evidence/runtime-startup-30/full-policy-diagnostic.jsonl +0 -3
- package/docs/evidence/runtime-startup-30/minimal-policy-diagnostic.jsonl +0 -3
- package/docs/evidence/runtime-startup-30/plugin-template-assessment.json +0 -20
- package/docs/evidence/runtime-startup-30/seedless-timeout.jsonl +0 -2
- package/docs/evidence.md +0 -17
- package/docs/fixture-cleanup-validation.md +0 -73
- package/docs/guide-verification.json +0 -239
- package/src/evaluation-context.ts +0 -259
- package/src/evaluation-fixture.ts +0 -302
- package/src/evaluation-run.ts +0 -200
- package/src/evaluation-trial.ts +0 -1016
- package/src/hosts/claude-nested-skills.ts +0 -272
- package/src/hosts/codex-command-output.ts +0 -510
- package/src/hosts/codex-executor-command.ts +0 -291
- package/src/hosts/codex-skill-reads.ts +0 -783
- /package/src/{trial-scheduler.ts → evaluation/scheduler.ts} +0 -0
package/src/hosts/codex-state.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { runtimeSeedSources } from "../runtime
|
|
1
|
+
import { runtimeLocalHttpEnabled, runtimeSeedSources } from "../runtime/config";
|
|
2
|
+
import { shellQuote } from "../shell";
|
|
2
3
|
import {
|
|
3
4
|
candidateArtifactEnvironment,
|
|
4
5
|
candidateArtifactReadRoots,
|
|
5
6
|
} from "../candidate-artifacts";
|
|
7
|
+
import {
|
|
8
|
+
codexStateEnabled,
|
|
9
|
+
retainCandidateCodexState,
|
|
10
|
+
} from "../candidate-codex-state";
|
|
6
11
|
import { randomUUID } from "node:crypto";
|
|
7
12
|
import { existsSync } from "node:fs";
|
|
13
|
+
import { isMissingFile } from "../fixtures/tools";
|
|
8
14
|
import {
|
|
9
15
|
cp,
|
|
16
|
+
lstat,
|
|
10
17
|
mkdir,
|
|
11
18
|
readFile,
|
|
12
19
|
realpath,
|
|
@@ -21,12 +28,17 @@ import {
|
|
|
21
28
|
candidateTranscriptEnvironment,
|
|
22
29
|
candidateTranscriptRoots,
|
|
23
30
|
} from "../native-transcripts";
|
|
24
|
-
import { prepareHookMounts } from "../runtime
|
|
31
|
+
import { prepareHookMounts } from "../runtime/hooks";
|
|
32
|
+
import { requireNativeHookRoots } from "../native-transcript-state";
|
|
25
33
|
import {
|
|
26
34
|
requireRuntimeReadRoots,
|
|
27
35
|
runtimeExecutableProtection,
|
|
28
|
-
} from "../runtime
|
|
29
|
-
import { prepareRuntimeState } from "../runtime
|
|
36
|
+
} from "../runtime/paths";
|
|
37
|
+
import { prepareRuntimeState } from "../runtime/state";
|
|
38
|
+
import {
|
|
39
|
+
sharedCacheDenyRoots,
|
|
40
|
+
sharedCacheRoots,
|
|
41
|
+
} from "../runtime/shared-cache";
|
|
30
42
|
import { codexPermissionProfile } from "./codex-profile";
|
|
31
43
|
import { evaluationProtectedRoots } from "./isolation-roots";
|
|
32
44
|
type Request = Parameters<HostAdapter["run"]>[0];
|
|
@@ -44,6 +56,7 @@ export interface CodexHostOptions {
|
|
|
44
56
|
agentConcurrencyLimit?: number | null;
|
|
45
57
|
timeoutMs?: number;
|
|
46
58
|
entrypoint?: "exec" | "app-server";
|
|
59
|
+
retainHostDiagnostics?: boolean;
|
|
47
60
|
/** Integration-test seam; production uses the same CLI for execution and preflight. */
|
|
48
61
|
sandboxBinary?: string;
|
|
49
62
|
}
|
|
@@ -64,23 +77,22 @@ async function copyAuth(source: string, target: string): Promise<void> {
|
|
|
64
77
|
await writeFile(target, bytes, { flag: "wx", mode: 0o600 });
|
|
65
78
|
}
|
|
66
79
|
|
|
67
|
-
function shellQuote(value: string): string {
|
|
68
|
-
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
80
|
export async function codexHookMounts(
|
|
72
81
|
request: Request,
|
|
73
82
|
state: CodexState,
|
|
74
83
|
installedPluginRoots: string[],
|
|
75
84
|
) {
|
|
76
|
-
if (!request.runtimePolicy) return undefined;
|
|
77
85
|
const hooks = await prepareHookMounts({
|
|
78
86
|
workspace: request.workspace,
|
|
79
|
-
stateRoot:
|
|
87
|
+
stateRoot: state.stateRoot,
|
|
80
88
|
privateRoot: state.codexHome,
|
|
81
89
|
pluginRoots: installedPluginRoots,
|
|
82
90
|
protectedRoots: state.protectedRoots,
|
|
83
|
-
policy: request.runtimePolicy
|
|
91
|
+
policy: request.runtimePolicy ?? {
|
|
92
|
+
format: "sevro.runtime.v1",
|
|
93
|
+
environment: {},
|
|
94
|
+
readOnlyRoots: [],
|
|
95
|
+
},
|
|
84
96
|
});
|
|
85
97
|
for (const [index, root] of installedPluginRoots.entries()) {
|
|
86
98
|
const curated = hooks.directories[index];
|
|
@@ -88,9 +100,28 @@ export async function codexHookMounts(
|
|
|
88
100
|
await rm(root, { recursive: true });
|
|
89
101
|
await cp(curated, root, { recursive: true });
|
|
90
102
|
}
|
|
103
|
+
await grantCodexHookReads(state, hooks.directories);
|
|
91
104
|
return hooks;
|
|
92
105
|
}
|
|
93
106
|
|
|
107
|
+
/** Hooks advertise paths relative to these curated copies, not the install cache. */
|
|
108
|
+
async function grantCodexHookReads(
|
|
109
|
+
state: CodexState,
|
|
110
|
+
roots: string[],
|
|
111
|
+
): Promise<void> {
|
|
112
|
+
if (roots.length === 0) return;
|
|
113
|
+
await requireNativeHookRoots(roots, state.codexHome);
|
|
114
|
+
const path = join(state.codexHome, "config.toml");
|
|
115
|
+
const config = await readFile(path, "utf8");
|
|
116
|
+
const header = `[permissions.${state.profileId}.filesystem]\n`;
|
|
117
|
+
const grants = roots
|
|
118
|
+
.map((root) => `${JSON.stringify(root)} = "read"\n`)
|
|
119
|
+
.join("");
|
|
120
|
+
await writeFile(path, config.replace(header, header + grants), {
|
|
121
|
+
mode: 0o600,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
94
125
|
async function privateCodexDirectories(stateRoot: string) {
|
|
95
126
|
const codexHome = join(stateRoot, "codex-home"),
|
|
96
127
|
parentHome = join(stateRoot, "home"),
|
|
@@ -145,9 +176,14 @@ async function writeCodexProfile(
|
|
|
145
176
|
protectedRoots: string[],
|
|
146
177
|
limit: number | null,
|
|
147
178
|
commandEnvironment = request.runtimePolicy?.environment,
|
|
148
|
-
runtimeWriteRoot
|
|
179
|
+
runtimeWriteRoot: string | undefined,
|
|
180
|
+
writableCacheRoots: string[],
|
|
149
181
|
): Promise<void> {
|
|
150
182
|
const profile = codexPermissionProfile({
|
|
183
|
+
localHttp: runtimeLocalHttpEnabled(
|
|
184
|
+
request.runtimePolicy,
|
|
185
|
+
request.runtimeRole ?? "candidate",
|
|
186
|
+
),
|
|
151
187
|
commandEnvironment: codexProfileEnvironment(
|
|
152
188
|
request,
|
|
153
189
|
paths,
|
|
@@ -156,6 +192,10 @@ async function writeCodexProfile(
|
|
|
156
192
|
runtimeWriteRoot,
|
|
157
193
|
runtimeReadRoots: request.runtimePolicy?.readOnlyRoots,
|
|
158
194
|
nativeReadRoots: codexNativeReadRoots(request, paths.codexHome),
|
|
195
|
+
nativeWriteRoots: [
|
|
196
|
+
...codexStateWriteRoots(request, paths),
|
|
197
|
+
...writableCacheRoots,
|
|
198
|
+
],
|
|
159
199
|
id: profileId,
|
|
160
200
|
workspace: request.workspace,
|
|
161
201
|
commandHome: paths.commandHome,
|
|
@@ -166,11 +206,17 @@ async function writeCodexProfile(
|
|
|
166
206
|
});
|
|
167
207
|
await writeFile(
|
|
168
208
|
join(paths.codexHome, "config.toml"),
|
|
169
|
-
profile +
|
|
209
|
+
profile +
|
|
210
|
+
concurrencyConfiguration(limit) +
|
|
211
|
+
fixtureTrustConfiguration(request),
|
|
170
212
|
{ flag: "wx", mode: 0o600 },
|
|
171
213
|
);
|
|
172
214
|
}
|
|
173
215
|
|
|
216
|
+
function fixtureTrustConfiguration(request: Request): string {
|
|
217
|
+
return `\n[projects.${JSON.stringify(request.workspace)}]\ntrust_level = "untrusted"\n`;
|
|
218
|
+
}
|
|
219
|
+
|
|
174
220
|
function codexProfileEnvironment(
|
|
175
221
|
request: Request,
|
|
176
222
|
paths: Awaited<ReturnType<typeof privateCodexDirectories>>,
|
|
@@ -181,6 +227,11 @@ function codexProfileEnvironment(
|
|
|
181
227
|
...codexTranscriptEnvironment(request, paths.codexHome),
|
|
182
228
|
...candidateTranscriptEnvironment(request.candidateTranscriptRoot),
|
|
183
229
|
...candidateArtifactEnvironment(request.candidateArtifactRoots),
|
|
230
|
+
...(request.runtimePolicy?.codexState === true
|
|
231
|
+
? {
|
|
232
|
+
SEVRO_CODEX_AGENT_SKILLS: join(paths.parentHome, ".agents", "skills"),
|
|
233
|
+
}
|
|
234
|
+
: {}),
|
|
184
235
|
};
|
|
185
236
|
}
|
|
186
237
|
|
|
@@ -188,14 +239,23 @@ function codexTranscriptEnvironment(
|
|
|
188
239
|
request: Request,
|
|
189
240
|
home: string,
|
|
190
241
|
): Record<string, string> {
|
|
191
|
-
return
|
|
192
|
-
? { CODEX_HOME: home
|
|
193
|
-
|
|
242
|
+
return {
|
|
243
|
+
...(request.runtimePolicy?.codexState === true ? { CODEX_HOME: home } : {}),
|
|
244
|
+
...(request.runtimePolicy?.nativeTranscripts === true
|
|
245
|
+
? {
|
|
246
|
+
CODEX_HOME: home,
|
|
247
|
+
SEVRO_NATIVE_TRANSCRIPT_ROOT: join(home, "sessions"),
|
|
248
|
+
}
|
|
249
|
+
: {}),
|
|
250
|
+
};
|
|
194
251
|
}
|
|
195
252
|
|
|
196
253
|
function codexNativeReadRoots(request: Request, home: string) {
|
|
197
254
|
return [
|
|
198
255
|
...linuxArg0ReadRoots(home),
|
|
256
|
+
...(request.runtimePolicy?.codexState === true
|
|
257
|
+
? [join(home, "config.toml"), join(home, "skills", ".system")]
|
|
258
|
+
: []),
|
|
199
259
|
...codexTranscriptRoots(request, home),
|
|
200
260
|
...candidateTranscriptRoots(request.candidateTranscriptRoot),
|
|
201
261
|
...candidateArtifactReadRoots(request.candidateArtifactRoots),
|
|
@@ -321,7 +381,11 @@ function applyCodexRuntime(
|
|
|
321
381
|
function codexRuntimeProfile(
|
|
322
382
|
runtime: Awaited<ReturnType<typeof codexRuntime>>,
|
|
323
383
|
) {
|
|
324
|
-
return {
|
|
384
|
+
return {
|
|
385
|
+
environment: runtime?.environment,
|
|
386
|
+
root: runtime?.root,
|
|
387
|
+
writableCacheRoots: runtime?.writableCacheRoots ?? [],
|
|
388
|
+
};
|
|
325
389
|
}
|
|
326
390
|
|
|
327
391
|
export async function prepareCodexState(
|
|
@@ -331,6 +395,7 @@ export async function prepareCodexState(
|
|
|
331
395
|
request: Request,
|
|
332
396
|
helperRoot?: string,
|
|
333
397
|
) {
|
|
398
|
+
await requireIsolatedGitMetadata(request.workspace);
|
|
334
399
|
const paths = await privateCodexDirectories(stateRoot);
|
|
335
400
|
const runtime = await codexRuntime(request, paths, stateRoot);
|
|
336
401
|
await copyAuth(options.authFile, join(paths.codexHome, "auth.json"));
|
|
@@ -356,6 +421,14 @@ export async function prepareCodexState(
|
|
|
356
421
|
);
|
|
357
422
|
if (helperRoot) readRoots.push(helperRoot);
|
|
358
423
|
requireCodexRuntimeReadRoots(request, protectedRoots);
|
|
424
|
+
await sharedCacheRoots(
|
|
425
|
+
request.runtimePolicy,
|
|
426
|
+
request.runtimeRole,
|
|
427
|
+
protectedRoots,
|
|
428
|
+
);
|
|
429
|
+
protectedRoots.push(
|
|
430
|
+
...sharedCacheDenyRoots(request.runtimePolicy, request.runtimeRole),
|
|
431
|
+
);
|
|
359
432
|
requireUnprotectedExecutables(
|
|
360
433
|
readRoots,
|
|
361
434
|
runtimeExecutableProtection(
|
|
@@ -375,11 +448,54 @@ export async function prepareCodexState(
|
|
|
375
448
|
limit,
|
|
376
449
|
runtimeProfile.environment,
|
|
377
450
|
runtimeProfile.root,
|
|
451
|
+
runtimeProfile.writableCacheRoots,
|
|
378
452
|
);
|
|
379
453
|
const shellRoot = await fixtureShellRoot(request, paths.parentHome);
|
|
380
454
|
const env = codexEnvironment(paths, request, shellRoot);
|
|
381
455
|
applyCodexRuntime(runtime, env, paths);
|
|
382
|
-
|
|
456
|
+
await prepareCodexStateEvidence(request, stateRoot, paths);
|
|
457
|
+
return { ...paths, stateRoot, sandboxBinary, profileId, env, protectedRoots };
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function codexStateWriteRoots(
|
|
461
|
+
request: Request,
|
|
462
|
+
paths: Awaited<ReturnType<typeof privateCodexDirectories>>,
|
|
463
|
+
): string[] {
|
|
464
|
+
return codexStateEnabled(request.runtimePolicy)
|
|
465
|
+
? [
|
|
466
|
+
join(paths.codexHome, "skills"),
|
|
467
|
+
join(paths.parentHome, ".agents", "skills"),
|
|
468
|
+
join(paths.commandHome, ".agents", "skills"),
|
|
469
|
+
join(paths.commandHome, ".codex", "skills"),
|
|
470
|
+
]
|
|
471
|
+
: [];
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
async function prepareCodexStateEvidence(
|
|
475
|
+
request: Request,
|
|
476
|
+
stateRoot: string,
|
|
477
|
+
paths: Awaited<ReturnType<typeof privateCodexDirectories>>,
|
|
478
|
+
): Promise<void> {
|
|
479
|
+
if (!codexStateEnabled(request.runtimePolicy)) return;
|
|
480
|
+
const skillRoots = codexStateWriteRoots(request, paths);
|
|
481
|
+
await Promise.all(
|
|
482
|
+
skillRoots.map((root) => mkdir(root, { recursive: true, mode: 0o700 })),
|
|
483
|
+
);
|
|
484
|
+
await mkdir(join(paths.codexHome, "skills", ".system"), { mode: 0o700 });
|
|
485
|
+
await retainCandidateCodexState(
|
|
486
|
+
request.candidateRuntimeRoot,
|
|
487
|
+
stateRoot,
|
|
488
|
+
paths,
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
async function requireIsolatedGitMetadata(workspace: string): Promise<void> {
|
|
493
|
+
try {
|
|
494
|
+
if (!(await lstat(join(workspace, ".git"))).isDirectory())
|
|
495
|
+
throw new Error("Codex Git metadata must be an isolated directory");
|
|
496
|
+
} catch (cause) {
|
|
497
|
+
if (!isMissingFile(cause)) throw cause;
|
|
498
|
+
}
|
|
383
499
|
}
|
|
384
500
|
|
|
385
501
|
function requireCodexRuntimeReadRoots(
|