@vela-science/canopus 0.7.0 → 0.8.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +67 -145
  3. package/capsules/erdos1056-k15/bin/linux-arm64/{10428801-10429000 → 10429201-10429400}/verifier +0 -0
  4. package/capsules/erdos1056-k15/bin/linux-x86_64/{10428801-10429000 → 10429201-10429400}/verifier +0 -0
  5. package/compatibility.json +25 -0
  6. package/dist/src/{receipt/map.d.ts → candidate/finalize.d.ts} +2 -9
  7. package/dist/src/candidate/finalize.js +71 -0
  8. package/dist/src/cli.js +89 -195
  9. package/dist/src/contracts/mission.d.ts +1 -13
  10. package/dist/src/contracts/mission.js +4 -42
  11. package/dist/src/contracts/validation.d.ts +1 -25
  12. package/dist/src/contracts/validation.js +1 -95
  13. package/dist/src/engines/codex-tools-native.js +2 -2
  14. package/dist/src/index.d.ts +5 -34
  15. package/dist/src/index.js +4 -34
  16. package/dist/src/mission/prepare.d.ts +10 -1
  17. package/dist/src/mission/prepare.js +29 -30
  18. package/dist/src/product/coverage.d.ts +17 -0
  19. package/dist/src/product/coverage.js +137 -0
  20. package/dist/src/product/doctor.d.ts +1 -2
  21. package/dist/src/product/doctor.js +29 -8
  22. package/dist/src/product/profile.js +8 -2
  23. package/dist/src/product/replay.js +11 -12
  24. package/dist/src/product/run.d.ts +5 -9
  25. package/dist/src/product/run.js +17 -81
  26. package/dist/src/product/submission.d.ts +40 -0
  27. package/dist/src/product/submission.js +217 -0
  28. package/dist/src/product/submit.d.ts +22 -0
  29. package/dist/src/product/submit.js +264 -0
  30. package/dist/src/product/version.d.ts +2 -2
  31. package/dist/src/product/version.js +27 -4
  32. package/dist/src/projection/current-run.d.ts +12 -0
  33. package/dist/src/projection/current-run.js +94 -0
  34. package/dist/src/projection/failure.d.ts +17 -7
  35. package/dist/src/projection/failure.js +43 -12
  36. package/dist/src/projection/retained-mission.d.ts +6 -0
  37. package/dist/src/projection/retained-mission.js +41 -0
  38. package/dist/src/projection/retained-run.d.ts +7 -0
  39. package/dist/src/projection/retained-run.js +50 -0
  40. package/dist/src/run.d.ts +43 -34
  41. package/dist/src/run.js +34 -397
  42. package/dist/src/util/canonical.d.ts +1 -5
  43. package/dist/src/util/canonical.js +1 -53
  44. package/dist/src/vela/cli.d.ts +7 -42
  45. package/dist/src/vela/cli.js +102 -475
  46. package/dist/src/vela/types.d.ts +3 -19
  47. package/dist/src/verifier/run.js +1 -1
  48. package/dist/src/workspace/prepare.d.ts +1 -1
  49. package/dist/src/workspace/prepare.js +15 -15
  50. package/docs/EVALUATION.md +142 -0
  51. package/docs/MISSIONS.md +42 -80
  52. package/docs/RUN_RECORD.md +77 -99
  53. package/docs/adr/0010-nonmutating-runs-and-explicit-submission.md +191 -0
  54. package/missions/erdos1056-k15-next/mission.draft.json +10 -8
  55. package/package.json +18 -15
  56. package/profiles/{erdos1056-k15-10428801-10429000.json → erdos1056-k15-10429201-10429400.json} +10 -10
  57. package/schemas/failure.v1.json +17 -0
  58. package/schemas/mission.v0.json +3 -4
  59. package/schemas/mission.v1.json +7 -28
  60. package/schemas/{run.v1.json → run.v2.json} +58 -116
  61. package/schemas/submission-bundle.v1.json +63 -0
  62. package/toolchain.lock.json +31 -0
  63. package/capsules/formal-erdos-505-test-dim-one/verifier +0 -105
  64. package/capsules/quantum-10-1-4/verifier.py +0 -152
  65. package/capsules/sidon-a24/bin/linux-arm64/verifier +0 -0
  66. package/capsules/sidon-a24/bin/linux-x86_64/verifier +0 -0
  67. package/dist/src/engines/codex-exec.d.ts +0 -17
  68. package/dist/src/engines/codex-exec.js +0 -136
  69. package/dist/src/engines/codex-tool-free.d.ts +0 -26
  70. package/dist/src/engines/codex-tool-free.js +0 -213
  71. package/dist/src/projection/diagnostic.d.ts +0 -12
  72. package/dist/src/projection/diagnostic.js +0 -61
  73. package/dist/src/projection/public-run.d.ts +0 -59
  74. package/dist/src/projection/public-run.js +0 -106
  75. package/dist/src/projection/publication.d.ts +0 -36
  76. package/dist/src/projection/publication.js +0 -47
  77. package/dist/src/projection/run.d.ts +0 -95
  78. package/dist/src/projection/run.js +0 -173
  79. package/dist/src/receipt/map.js +0 -168
  80. package/dist/src/repair/plan.d.ts +0 -2
  81. package/dist/src/repair/plan.js +0 -22
  82. package/dist/src/roles.d.ts +0 -2
  83. package/dist/src/roles.js +0 -9
  84. package/missions/formal-erdos-505-test-dim-one-gpt56/mission.draft.json +0 -40
  85. package/missions/quantum-10-1-4-retry/mission.draft.json +0 -40
  86. package/missions/sidon-a24-at-least-7194-gpt56/mission.draft.json +0 -42
  87. package/missions/sidon-a24-at-least-7194-gpt56-v2/mission.draft.json +0 -42
  88. package/missions/sidon-a24-at-least-7194-gpt56-v3/mission.draft.json +0 -42
  89. package/profiles/formal-erdos-505-test-dim-one-gpt56.json +0 -35
  90. package/profiles/quantum-10-1-4-stabilizer-retry.json +0 -35
  91. package/profiles/sidon-a24-at-least-7194-gpt56-v2.json +0 -35
  92. package/profiles/sidon-a24-at-least-7194-gpt56-v3.json +0 -35
  93. package/profiles/sidon-a24-at-least-7194-gpt56.json +0 -35
  94. package/schemas/canopus.public-run.v1.json +0 -116
@@ -1,136 +0,0 @@
1
- import path from "node:path";
2
- import { parseCandidateDraft, assertDraftArtifactsAllowed } from "../candidate/validate.js";
3
- import { roleInstruction } from "../roles.js";
4
- import { canonicalJson, contentDigest, sha256Bytes } from "../util/canonical.js";
5
- import { isolatedEnvironment, runCommand, } from "../util/command.js";
6
- import { MAX_EXECUTABLE_BYTES, readBoundedRegularFile, sha256RegularFile } from "../util/files.js";
7
- import { parseCodexEvents, summarizeCodexFailure } from "./codex-events.js";
8
- import { prepareIsolatedCodexHome, removeIsolatedCodexHome } from "./codex-home.js";
9
- import { CODEX_TOOL_FEATURES, sandboxedToolFreeCodexExecArgv, } from "./codex-tool-free.js";
10
- function prompt(mission, briefing) {
11
- return [
12
- "Execute one bounded Canopus research mission.",
13
- roleInstruction(mission.role),
14
- "This is a tool-free synthesis stage. You cannot inspect the host or run commands.",
15
- "Use only the mission and the exact Vela work briefing supplied below.",
16
- "Return artifact bytes inline as UTF-8 content. The trusted harness materializes and verifies them later.",
17
- "Do not request tools, network access, external messages, Vela signing, human keys, or accepted-state writes.",
18
- "Worker status reports producer completion, not verifier or scientific standing. Return status success when you produced all artifact bytes required by the output contract, while stating that separate verification remains pending.",
19
- "Return null only when the bounded work produced no candidate, and failed only when you could not produce a contract-complete candidate or observed disqualifying evidence. Do not turn verifier failure into a success claim.",
20
- "Return only the supplied engine-output JSON shape.",
21
- "Mission:",
22
- canonicalJson(mission),
23
- "Vela work briefing:",
24
- canonicalJson(briefing),
25
- ].join("\n");
26
- }
27
- export class CodexExecEngine {
28
- name = "codex-exec";
29
- #options;
30
- #runner;
31
- constructor(options) {
32
- this.#options = options;
33
- this.#runner = options.runner ?? runCommand;
34
- }
35
- async #version(cwd, home, timeoutMs) {
36
- const result = await this.#runner({
37
- argv: [this.#options.binary, "--version"],
38
- cwd,
39
- env: isolatedEnvironment(home),
40
- timeoutMs,
41
- maxOutputBytes: 4096,
42
- });
43
- const version = result.stdout.toString("utf8").trim();
44
- if (result.exitCode !== 0 || result.stderr.length !== 0 || version !== this.#options.expectedVersion) {
45
- throw new Error(`expected Codex ${this.#options.expectedVersion}, observed ${JSON.stringify(version)}`);
46
- }
47
- return version;
48
- }
49
- async run(context) {
50
- context.budget.beginAttempt();
51
- const binaryDigest = await sha256RegularFile(this.#options.binary, MAX_EXECUTABLE_BYTES);
52
- if (binaryDigest !== this.#options.expectedSha256) {
53
- throw new Error(`Codex binary digest mismatch: expected ${this.#options.expectedSha256}, observed ${binaryDigest}`);
54
- }
55
- context.budget.beginProcess();
56
- const finalPath = path.join(context.paths.work, ".canopus-final.json");
57
- const version = await this.#version(context.paths.work, context.paths.home, context.budget.remainingTimeMs());
58
- context.budget.beginProcess();
59
- const runtimeCodexHome = await prepareIsolatedCodexHome(this.#options.authHome, context.paths.home);
60
- try {
61
- const environment = {
62
- ...isolatedEnvironment(context.paths.home),
63
- CODEX_HOME: runtimeCodexHome,
64
- NO_COLOR: "1",
65
- };
66
- const argv = await sandboxedToolFreeCodexExecArgv({
67
- binary: this.#options.binary,
68
- model: this.#options.model,
69
- outputSchema: this.#options.outputSchema,
70
- finalPath,
71
- cwd: context.paths.work,
72
- authHome: runtimeCodexHome,
73
- });
74
- const started = performance.now();
75
- const workerPrompt = prompt(context.mission, context.briefing);
76
- context.budget.addPrompt(Buffer.byteLength(workerPrompt));
77
- const result = await this.#runner({
78
- argv,
79
- cwd: context.paths.work,
80
- env: environment,
81
- timeoutMs: context.budget.remainingTimeMs(),
82
- maxOutputBytes: context.budget.remainingOutputBytes(),
83
- stdin: workerPrompt,
84
- });
85
- context.budget.addOutput(result.stdout.length + result.stderr.length);
86
- if (result.exitCode !== 0) {
87
- throw new Error(`codex exec exited ${result.exitCode}: ` +
88
- `${summarizeCodexFailure(result.stdout.toString("utf8"))}; ` +
89
- `stdout_sha256=${sha256Bytes(result.stdout)}; stderr_sha256=${sha256Bytes(result.stderr)}`);
90
- }
91
- const events = parseCodexEvents(result.stdout.toString("utf8"));
92
- if (events.actionTypes.length !== 0) {
93
- throw new Error(`tool-free Codex worker emitted actions: ${events.actionTypes.join(",")}`);
94
- }
95
- context.budget.addTokens(events.usage.input_tokens + events.usage.output_tokens);
96
- const finalBytes = await readBoundedRegularFile(finalPath, 1_048_576);
97
- context.budget.addOutput(finalBytes.length);
98
- let raw;
99
- try {
100
- raw = JSON.parse(finalBytes.toString("utf8"));
101
- }
102
- catch (error) {
103
- throw new Error(`Codex final response is not JSON: ${String(error)}`);
104
- }
105
- const draft = parseCandidateDraft(raw);
106
- assertDraftArtifactsAllowed(draft, context.mission.allowed_paths);
107
- return {
108
- draft,
109
- engine: {
110
- name: this.name,
111
- version,
112
- binary_sha256: binaryDigest,
113
- model: this.#options.model,
114
- configuration_sha256: contentDigest({
115
- binary_sha256: binaryDigest,
116
- codex_version: version,
117
- disabled_features: CODEX_TOOL_FEATURES,
118
- model: this.#options.model,
119
- output_schema_sha256: sha256Bytes(await readBoundedRegularFile(this.#options.outputSchema, 1_048_576)),
120
- outer_sandbox: "macos_seatbelt_bounded_reads",
121
- product_sandbox: "read-only",
122
- }),
123
- },
124
- usage: events.usage,
125
- wallTimeMs: Math.max(0, Math.round(performance.now() - started)),
126
- eventTypes: events.eventTypes,
127
- actionTypes: events.actionTypes,
128
- eventsDigest: sha256Bytes(result.stdout),
129
- stderrDigest: sha256Bytes(result.stderr),
130
- };
131
- }
132
- finally {
133
- await removeIsolatedCodexHome(runtimeCodexHome);
134
- }
135
- }
136
- }
@@ -1,26 +0,0 @@
1
- export declare const CODEX_TOOL_FEATURES: readonly ["apply_patch_freeform", "apply_patch_streaming_events", "apps", "artifact", "browser_use", "browser_use_external", "computer_use", "enable_mcp_apps", "goals", "hooks", "image_generation", "in_app_browser", "memories", "multi_agent", "plugin_sharing", "remote_plugin", "shell_snapshot", "shell_tool", "tool_suggest", "unified_exec", "workspace_dependencies"];
2
- export interface ToolFreeCodexArgs {
3
- binary: string;
4
- model: string;
5
- outputSchema: string;
6
- finalPath: string;
7
- cwd: string;
8
- reasoningEffort?: string;
9
- }
10
- export interface SandboxedToolFreeCodexArgs extends ToolFreeCodexArgs {
11
- authHome: string;
12
- }
13
- /**
14
- * Wrap Codex itself in a host read boundary. Codex 0.139 always registers
15
- * view_image even when every feature-backed tool is disabled, so this outer
16
- * sandbox is the control that makes an arbitrary host image unreadable.
17
- */
18
- export declare function sandboxedToolFreeCodexExecArgv(options: SandboxedToolFreeCodexArgs): Promise<string[]>;
19
- /**
20
- * Build the complete, pinned Codex lane used for untrusted synthesis.
21
- *
22
- * Read-only sandboxing alone still permits host reads. This lane registers no
23
- * shell, patch, browser, app, MCP, memory, or computer-use surface at all.
24
- * The only accepted product is the final response constrained by outputSchema.
25
- */
26
- export declare function toolFreeCodexExecArgv(options: ToolFreeCodexArgs): string[];
@@ -1,213 +0,0 @@
1
- import { access, realpath } from "node:fs/promises";
2
- import path from "node:path";
3
- export const CODEX_TOOL_FEATURES = [
4
- "apply_patch_freeform",
5
- "apply_patch_streaming_events",
6
- "apps",
7
- "artifact",
8
- "browser_use",
9
- "browser_use_external",
10
- "computer_use",
11
- "enable_mcp_apps",
12
- "goals",
13
- "hooks",
14
- "image_generation",
15
- "in_app_browser",
16
- "memories",
17
- "multi_agent",
18
- "plugin_sharing",
19
- "remote_plugin",
20
- "shell_snapshot",
21
- "shell_tool",
22
- "tool_suggest",
23
- "unified_exec",
24
- "workspace_dependencies",
25
- ];
26
- function sbpl(value) {
27
- return value.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
28
- }
29
- function metadataLiterals(paths) {
30
- const values = new Set(["/"]);
31
- for (const value of paths) {
32
- for (let current = value; current !== "/"; current = path.dirname(current)) {
33
- values.add(current);
34
- }
35
- }
36
- return [...values]
37
- .sort()
38
- .map((value) => `(literal "${sbpl(value)}")`)
39
- .join(" ");
40
- }
41
- async function optionalRealpath(candidate) {
42
- try {
43
- await access(candidate);
44
- return await realpath(candidate);
45
- }
46
- catch {
47
- return undefined;
48
- }
49
- }
50
- /**
51
- * Wrap Codex itself in a host read boundary. Codex 0.139 always registers
52
- * view_image even when every feature-backed tool is disabled, so this outer
53
- * sandbox is the control that makes an arbitrary host image unreadable.
54
- */
55
- export async function sandboxedToolFreeCodexExecArgv(options) {
56
- if (process.platform !== "darwin") {
57
- throw new Error("Canopus v0 requires the macOS outer Codex sandbox");
58
- }
59
- const lexical = {
60
- binary: path.resolve(options.binary),
61
- cwd: path.resolve(options.cwd),
62
- outputSchema: path.resolve(options.outputSchema),
63
- finalParent: path.resolve(path.dirname(options.finalPath)),
64
- authHome: path.resolve(options.authHome),
65
- authFile: path.resolve(options.authHome, "auth.json"),
66
- modelCatalog: path.resolve(options.authHome, "models_cache.json"),
67
- };
68
- const managedRequirements = [
69
- "/etc/codex/requirements.toml",
70
- "/private/etc/codex/requirements.toml",
71
- ];
72
- // These are public operating-system inputs used by the macOS resolver and
73
- // network stack. Keep the outer boundary file-specific: Codex does not need
74
- // the user's preferences, keychain, or arbitrary /etc contents.
75
- const networkRuntimeFiles = [
76
- "/Library/Preferences/com.apple.networkd.plist",
77
- "/etc/hosts",
78
- "/etc/protocols",
79
- "/etc/resolv.conf",
80
- "/etc/services",
81
- "/private/etc/hosts",
82
- "/private/etc/protocols",
83
- "/private/etc/resolv.conf",
84
- "/private/etc/services",
85
- "/private/var/run/resolv.conf",
86
- "/var/run/resolv.conf",
87
- ];
88
- const [binary, cwd, outputSchema, finalParent, authHome, authFile, modelCatalog] = await Promise.all([
89
- realpath(lexical.binary),
90
- realpath(lexical.cwd),
91
- realpath(lexical.outputSchema),
92
- realpath(lexical.finalParent),
93
- realpath(lexical.authHome),
94
- optionalRealpath(lexical.authFile),
95
- optionalRealpath(lexical.modelCatalog),
96
- ]);
97
- if (authFile === undefined) {
98
- throw new Error("Codex auth home has no readable auth.json");
99
- }
100
- const finalPath = path.join(finalParent, path.basename(options.finalPath));
101
- const inner = toolFreeCodexExecArgv({
102
- ...options,
103
- binary,
104
- cwd,
105
- outputSchema,
106
- finalPath,
107
- });
108
- const readableFiles = [
109
- binary,
110
- lexical.binary,
111
- outputSchema,
112
- lexical.outputSchema,
113
- authFile,
114
- authHome,
115
- lexical.authFile,
116
- lexical.authHome,
117
- modelCatalog,
118
- ...networkRuntimeFiles,
119
- ...(modelCatalog === undefined ? [] : [lexical.modelCatalog]),
120
- ]
121
- .filter((item) => item !== undefined)
122
- .filter((item, index, values) => values.indexOf(item) === index)
123
- .map((item) => `(literal "${sbpl(item)}")`)
124
- .join(" ");
125
- const metadata = metadataLiterals([
126
- binary,
127
- cwd,
128
- outputSchema,
129
- finalPath,
130
- authFile,
131
- lexical.binary,
132
- lexical.cwd,
133
- lexical.outputSchema,
134
- lexical.finalParent,
135
- lexical.authFile,
136
- ...managedRequirements,
137
- ...networkRuntimeFiles,
138
- ...(modelCatalog === undefined ? [] : [modelCatalog]),
139
- ]);
140
- const profile = [
141
- "(version 1)",
142
- "(deny default)",
143
- '(import "dyld-support.sb")',
144
- "(deny file-link file-clone)",
145
- // Native Codex creates runtime threads after entering Seatbelt. macOS
146
- // classifies that operation under process-fork; process-exec remains
147
- // restricted to the checksum-pinned Codex binary below.
148
- "(allow process-fork)",
149
- "(allow process-info* (target same-sandbox))",
150
- "(allow signal (target same-sandbox))",
151
- `(allow file-read-metadata ${metadata})`,
152
- `(allow process-exec (literal "${sbpl(binary)}"))`,
153
- `(allow file-map-executable (literal "${sbpl(binary)}"))`,
154
- '(allow sysctl-read (sysctl-name "hw.activecpu") (sysctl-name "hw.logicalcpu") (sysctl-name "hw.machine") (sysctl-name "hw.model") (sysctl-name "hw.ncpu") (sysctl-name "hw.pagesize") (sysctl-name "hw.pagesize_compat") (sysctl-name "kern.argmax") (sysctl-name "kern.hostname") (sysctl-name "kern.osproductversion") (sysctl-name "kern.osrelease") (sysctl-name "kern.ostype") (sysctl-name "kern.osversion") (sysctl-name "kern.usrstack64") (sysctl-name "kern.version") (sysctl-name-regex #"^net.routetable"))',
155
- // This is the finite service set required by native Codex startup plus the
156
- // DNS/TLS services in Codex's own macOS network policy. No wildcard Mach
157
- // lookup or user application service is admitted.
158
- '(allow mach-lookup (global-name "com.apple.SecurityServer") (global-name "com.apple.SystemConfiguration.DNSConfiguration") (global-name "com.apple.SystemConfiguration.configd") (global-name "com.apple.bsd.dirhelper") (global-name "com.apple.cfprefsd.agent") (local-name "com.apple.cfprefsd.agent") (global-name "com.apple.logd") (global-name "com.apple.networkd") (global-name "com.apple.ocspd") (global-name "com.apple.system.notification_center") (global-name "com.apple.system.opendirectoryd.libinfo") (global-name "com.apple.system.opendirectoryd.membership") (global-name "com.apple.trustd") (global-name "com.apple.trustd.agent"))',
159
- '(allow ipc-posix-shm-read* (ipc-posix-name "apple.shm.notification_center") (ipc-posix-name-prefix "apple.cfprefs."))',
160
- '(allow system-socket (require-all (socket-domain AF_SYSTEM) (socket-protocol 2)))',
161
- '(allow system-socket (socket-domain AF_UNIX))',
162
- '(allow file-read* (subpath "/Library/Apple") (subpath "/System") (subpath "/usr/lib") (subpath "/usr/share") (subpath "/private/etc/ssl") (subpath "/private/var/db/timezone") (literal "/dev/null") (literal "/dev/urandom"))',
163
- `(allow file-read* file-test-existence (subpath "${sbpl(cwd)}") (subpath "${sbpl(lexical.cwd)}") (subpath "${sbpl(authHome)}") (subpath "${sbpl(lexical.authHome)}") ${readableFiles})`,
164
- `(allow file-write* (subpath "${sbpl(authHome)}") (subpath "${sbpl(lexical.authHome)}") (literal "${sbpl(finalPath)}") (literal "/dev/null"))`,
165
- // Chromium's macOS network profile isolates the resolver socket from
166
- // ordinary IP traffic. This keeps AF_UNIX open only for mDNSResponder,
167
- // while permitting the model request over TCP/UDP.
168
- '(allow network-outbound (control-name "com.apple.netsrc") (literal "/private/var/run/mDNSResponder") (remote tcp) (remote udp))',
169
- ].join(" ");
170
- return ["/usr/bin/sandbox-exec", "-p", profile, "--", ...inner];
171
- }
172
- /**
173
- * Build the complete, pinned Codex lane used for untrusted synthesis.
174
- *
175
- * Read-only sandboxing alone still permits host reads. This lane registers no
176
- * shell, patch, browser, app, MCP, memory, or computer-use surface at all.
177
- * The only accepted product is the final response constrained by outputSchema.
178
- */
179
- export function toolFreeCodexExecArgv(options) {
180
- return [
181
- options.binary,
182
- "exec",
183
- "--ephemeral",
184
- "--skip-git-repo-check",
185
- "--ignore-user-config",
186
- "--ignore-rules",
187
- "--strict-config",
188
- "--sandbox",
189
- "read-only",
190
- "--model",
191
- options.model,
192
- "--output-schema",
193
- options.outputSchema,
194
- "--output-last-message",
195
- options.finalPath,
196
- "--json",
197
- "--color",
198
- "never",
199
- "--cd",
200
- options.cwd,
201
- "--config",
202
- "shell_environment_policy.inherit=none",
203
- "--config",
204
- "approval_policy=\"never\"",
205
- "--config",
206
- "web_search=\"disabled\"",
207
- ...(options.reasoningEffort === undefined
208
- ? []
209
- : ["--config", `model_reasoning_effort=\"${options.reasoningEffort}\"`]),
210
- ...CODEX_TOOL_FEATURES.flatMap((feature) => ["--disable", feature]),
211
- "-",
212
- ];
213
- }
@@ -1,12 +0,0 @@
1
- import type { DiagnosticRunRecord } from "../run.js";
2
- export declare function parseDiagnosticRunRecord(value: unknown): DiagnosticRunRecord;
3
- export declare function projectDiagnosticRun(record: DiagnosticRunRecord): {
4
- schema: "canopus.diagnostic-projection.v1";
5
- authority: "read_only_projection";
6
- run_id: string;
7
- target: string;
8
- candidate_digest: string;
9
- verifier_status: "passed" | "failed" | "error";
10
- landed: false;
11
- clean_clone_reproduced: true;
12
- };
@@ -1,61 +0,0 @@
1
- import { arrayAt, enumAt, exactKeys, objectAt, relativePathAt, sha256At, stringAt, } from "../contracts/validation.js";
2
- function literal(value, expected, at) {
3
- if (value !== expected)
4
- throw new Error(`${at} must be ${String(expected)}`);
5
- return expected;
6
- }
7
- export function parseDiagnosticRunRecord(value) {
8
- const record = objectAt(value, "diagnostic run");
9
- exactKeys(record, [
10
- "schema", "run_id", "status", "mode", "authority", "external_gate_credit",
11
- "mission", "candidate", "verifier", "landing", "reproduction", "budget",
12
- ], [], "diagnostic run");
13
- const mission = objectAt(record.mission, "diagnostic run.mission");
14
- exactKeys(mission, ["id", "target", "digest", "starting_roots"], [], "diagnostic run.mission");
15
- const candidate = objectAt(record.candidate, "diagnostic run.candidate");
16
- exactKeys(candidate, ["digest", "status", "claim", "artifacts", "caveats"], [], "diagnostic run.candidate");
17
- const verifier = objectAt(record.verifier, "diagnostic run.verifier");
18
- exactKeys(verifier, ["status", "sandbox", "record"], [], "diagnostic run.verifier");
19
- const reproduction = objectAt(record.reproduction, "diagnostic run.reproduction");
20
- exactKeys(reproduction, ["matched", "roots", "verifier_status", "stdout_digest", "stderr_digest"], [], "diagnostic run.reproduction");
21
- objectAt(mission.starting_roots, "diagnostic run.mission.starting_roots");
22
- objectAt(reproduction.roots, "diagnostic run.reproduction.roots");
23
- objectAt(record.budget, "diagnostic run.budget");
24
- literal(record.schema, "canopus.diagnostic-run.v1", "diagnostic run.schema");
25
- literal(record.status, "completed", "diagnostic run.status");
26
- literal(record.mode, "no_land", "diagnostic run.mode");
27
- literal(record.authority, "non_authoritative", "diagnostic run.authority");
28
- literal(record.external_gate_credit, false, "diagnostic run.external_gate_credit");
29
- literal(record.landing, null, "diagnostic run.landing");
30
- stringAt(record.run_id, "diagnostic run.run_id", { min: 5, max: 128 });
31
- stringAt(mission.id, "diagnostic run.mission.id", { min: 1, max: 134 });
32
- stringAt(mission.target, "diagnostic run.mission.target", { min: 1, max: 256 });
33
- sha256At(mission.digest, "diagnostic run.mission.digest");
34
- sha256At(candidate.digest, "diagnostic run.candidate.digest");
35
- enumAt(candidate.status, "diagnostic run.candidate.status", ["success", "null", "failed"]);
36
- stringAt(candidate.claim, "diagnostic run.candidate.claim", { min: 1, max: 8192 });
37
- arrayAt(candidate.artifacts, "diagnostic run.candidate.artifacts", { max: 10 }, (item, at) => {
38
- const artifact = objectAt(item, at);
39
- exactKeys(artifact, ["path", "kind", "digest", "bytes"], [], at);
40
- relativePathAt(artifact.path, `${at}.path`);
41
- stringAt(artifact.kind, `${at}.kind`, { min: 1, max: 128 });
42
- sha256At(artifact.digest, `${at}.digest`);
43
- return true;
44
- });
45
- arrayAt(candidate.caveats, "diagnostic run.candidate.caveats", { max: 10 }, (item, at) => stringAt(item, at, { min: 1, max: 4096 }));
46
- enumAt(verifier.status, "diagnostic run.verifier.status", ["passed", "failed", "error"]);
47
- literal(reproduction.matched, true, "diagnostic run.reproduction.matched");
48
- return value;
49
- }
50
- export function projectDiagnosticRun(record) {
51
- return {
52
- schema: "canopus.diagnostic-projection.v1",
53
- authority: "read_only_projection",
54
- run_id: record.run_id,
55
- target: record.mission.target,
56
- candidate_digest: record.candidate.digest,
57
- verifier_status: record.verifier.status,
58
- landed: false,
59
- clean_clone_reproduced: true,
60
- };
61
- }
@@ -1,59 +0,0 @@
1
- import type { Mission } from "../contracts/mission.js";
2
- import type { RunRecord } from "./run.js";
3
- export declare const PUBLIC_RUN_SCHEMA: "canopus.public-run.v1";
4
- export interface PublicRunProjection {
5
- schema: typeof PUBLIC_RUN_SCHEMA;
6
- authority: "read_only_projection";
7
- run_id: string;
8
- mission: {
9
- id: string;
10
- target: string;
11
- digest: string;
12
- registration_kind: "profile" | "mission_bundle";
13
- registration_name: string;
14
- registration_root: string;
15
- target_packet_root: string;
16
- model: string;
17
- };
18
- activity: {
19
- worker: "success";
20
- verifier: "pass";
21
- clean_clone_replay: "matched";
22
- };
23
- claim: string;
24
- caveats: string[];
25
- artifact_roots: string[];
26
- verifier_root: string;
27
- receipt_root: string;
28
- policy: {
29
- route: "defer";
30
- proposal_id: string;
31
- accepted_state_delta: 0;
32
- };
33
- usage: {
34
- research_elapsed_ms: number;
35
- research_processes: number;
36
- observed_tokens: number;
37
- attempts: number;
38
- };
39
- source: {
40
- repository: string;
41
- commit: string;
42
- event_log_root: string;
43
- snapshot_root: string;
44
- };
45
- final: {
46
- commit: string;
47
- event_log_root: string;
48
- snapshot_root: string;
49
- };
50
- reproduction: {
51
- commands: string[];
52
- };
53
- nonclaims: string[];
54
- }
55
- export declare function projectPublicRun(options: {
56
- record: RunRecord;
57
- mission: Mission;
58
- repository: string;
59
- }): PublicRunProjection;
@@ -1,106 +0,0 @@
1
- import { contentDigest } from "../util/canonical.js";
2
- export const PUBLIC_RUN_SCHEMA = "canopus.public-run.v1";
3
- function publicRepository(value) {
4
- if (!/^https:\/\/github\.com\/vela-science\/[a-z0-9-]+(?:\.git)?$/u.test(value)) {
5
- throw new Error("public run repository must be a public vela-science GitHub URL");
6
- }
7
- const url = value.endsWith(".git") ? value.slice(0, -4) : value;
8
- const directory = new URL(url).pathname.split("/").at(-1);
9
- if (directory === undefined || directory === "")
10
- throw new Error("public run repository is invalid");
11
- return { url, directory };
12
- }
13
- function publicCaveat(value) {
14
- if (/verif(?:y|ication|ier).*(?:pending|has not run)|pending.*verif(?:y|ication|ier)/iu.test(value)) {
15
- return "The worker handed off without verifier authority; Canopus subsequently recorded the separate verifier pass shown in this projection.";
16
- }
17
- return value;
18
- }
19
- function shellArgument(value) {
20
- return `'${value.replaceAll("'", `'"'"'`)}'`;
21
- }
22
- export function projectPublicRun(options) {
23
- const { record, mission } = options;
24
- if (mission.schema !== "canopus.mission.v1") {
25
- throw new Error("public run export requires a closed Mission v1 bundle");
26
- }
27
- if (contentDigest(mission) !== record.mission.digest) {
28
- throw new Error("public run mission bytes do not match the completed run");
29
- }
30
- if (mission.id !== record.mission.id || mission.target !== record.mission.target) {
31
- throw new Error("public run mission identity does not match the completed run");
32
- }
33
- if (record.candidate.status !== "success" || record.candidate.artifacts.length < 1) {
34
- throw new Error("public run export requires at least one successful bounded artifact");
35
- }
36
- if (record.verifier.status !== "passed" || record.reproduction.verifier_status !== "passed") {
37
- throw new Error("public run export requires verifier pass in both landing and replay");
38
- }
39
- if (!record.reproduction.matched) {
40
- throw new Error("public run export requires matched clean-clone replay");
41
- }
42
- if (record.landing.route !== "defer" || record.landing.accepted_event_delta !== 0) {
43
- throw new Error("public run export requires Defer with zero accepted-state delta");
44
- }
45
- const repository = publicRepository(options.repository);
46
- return {
47
- schema: PUBLIC_RUN_SCHEMA,
48
- authority: "read_only_projection",
49
- run_id: record.run_id,
50
- mission: {
51
- id: mission.id,
52
- target: mission.target,
53
- digest: record.mission.digest,
54
- registration_kind: mission.profile === undefined ? "mission_bundle" : "profile",
55
- registration_name: mission.profile?.name ?? mission.id,
56
- registration_root: mission.profile?.root ?? record.mission.digest,
57
- target_packet_root: mission.target_packet.sha256,
58
- model: mission.worker.model,
59
- },
60
- activity: {
61
- worker: "success",
62
- verifier: "pass",
63
- clean_clone_replay: "matched",
64
- },
65
- claim: record.candidate.claim,
66
- caveats: [...new Set(record.candidate.caveats.map(publicCaveat))],
67
- artifact_roots: record.candidate.artifacts.map((artifact) => artifact.digest).sort(),
68
- verifier_root: contentDigest(record.verifier),
69
- receipt_root: record.landing.receipt_root,
70
- policy: {
71
- route: "defer",
72
- proposal_id: record.landing.proposal_id,
73
- accepted_state_delta: 0,
74
- },
75
- usage: {
76
- research_elapsed_ms: record.budget.research_elapsed_ms,
77
- research_processes: record.budget.research_processes,
78
- observed_tokens: record.budget.observed_tokens,
79
- attempts: record.budget.attempts,
80
- },
81
- source: {
82
- repository: repository.url,
83
- commit: record.mission.starting_roots.git_commit,
84
- event_log_root: record.mission.starting_roots.vela_event_log,
85
- snapshot_root: record.mission.starting_roots.vela_snapshot,
86
- },
87
- final: {
88
- commit: record.final_roots.git_commit,
89
- event_log_root: record.final_roots.vela_event_log,
90
- snapshot_root: record.final_roots.vela_snapshot,
91
- },
92
- reproduction: {
93
- commands: [
94
- `git clone ${repository.url}.git`,
95
- `cd ${repository.directory}`,
96
- `git checkout ${record.final_roots.git_commit}`,
97
- ...mission.allowed_paths.map((artifact) => `vela reproduce ${shellArgument(artifact)}`),
98
- ],
99
- },
100
- nonclaims: [
101
- "Verifier success is not scientific acceptance.",
102
- "The bounded result does not establish maximality or settle the broader scientific problem.",
103
- "Canopus did not sign or perform a human decision.",
104
- ],
105
- };
106
- }
@@ -1,36 +0,0 @@
1
- import type { Mission } from "../contracts/mission.js";
2
- import type { RunRecord } from "./run.js";
3
- import { projectPublicRun } from "./public-run.js";
4
- export interface PublicationBundle {
5
- projection: ReturnType<typeof projectPublicRun>;
6
- pendingCommands: {
7
- schema: "canopus.pending-commands.v1";
8
- authority: "none";
9
- proposal_id: string;
10
- commands: Array<{
11
- purpose: string;
12
- authority: string;
13
- command: string;
14
- }>;
15
- };
16
- webImport: {
17
- schema: "vela-web.canopus-import.v1";
18
- authority: "read_only";
19
- run_id: string;
20
- projection_path: "public-run.json";
21
- projection_root: string;
22
- route: "defer";
23
- accepted_state_delta: 0;
24
- };
25
- manifest: {
26
- schema: "canopus.publication-manifest.v1";
27
- authority: "none";
28
- run_id: string;
29
- files: Record<string, string>;
30
- };
31
- }
32
- export declare function buildPublicationBundle(options: {
33
- record: RunRecord;
34
- mission: Mission;
35
- repository: string;
36
- }): PublicationBundle;