@bjoernrochel/sevro 0.1.0-rc.1
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/LICENSE +159 -0
- package/README.md +71 -0
- package/docs/advisory-fixture.md +23 -0
- package/docs/builtin-graders-v1.md +77 -0
- package/docs/cache-ownership-validation.md +49 -0
- package/docs/claude-continuation-validation.md +47 -0
- package/docs/codex-host.md +134 -0
- package/docs/concurrency-validation.md +86 -0
- package/docs/configuration-root-validation.md +70 -0
- package/docs/development-cli.md +327 -0
- package/docs/engine-slice.md +114 -0
- package/docs/extension-protocol-v1.md +292 -0
- package/docs/fixture-cleanup-validation.md +70 -0
- package/docs/identity-v1.md +65 -0
- package/docs/native-controls.md +29 -0
- package/docs/releases.md +88 -0
- package/docs/report-v1.md +32 -0
- package/docs/results-v1.md +118 -0
- package/examples/basic/graded.json +13 -0
- package/examples/basic/host.ts +8 -0
- package/examples/basic/prompt-only.json +7 -0
- package/package.json +45 -0
- package/schemas/cli-result-v1.schema.json +184 -0
- package/schemas/extension-v1.schema.json +659 -0
- package/schemas/report-v1.schema.json +164 -0
- package/schemas/run-evidence-v1.schema.json +510 -0
- package/src/advisory-fixture.ts +282 -0
- package/src/advisory.ts +105 -0
- package/src/cli.ts +837 -0
- package/src/engine.ts +2341 -0
- package/src/extension-client.ts +257 -0
- package/src/extension-session.ts +335 -0
- package/src/fixture-bin.ts +87 -0
- package/src/fixture-cleanup.ts +38 -0
- package/src/fixture-setup.ts +163 -0
- package/src/generated-fixture.ts +220 -0
- package/src/git-hooks.ts +63 -0
- package/src/graders/git-head.ts +176 -0
- package/src/graders/output.ts +359 -0
- package/src/graders/semantic.ts +120 -0
- package/src/graders/shell.ts +277 -0
- package/src/hosts/claude-continuation.ts +94 -0
- package/src/hosts/claude-credential.ts +73 -0
- package/src/hosts/claude-events.ts +128 -0
- package/src/hosts/claude-nested-skills.ts +218 -0
- package/src/hosts/claude-repository-invocation.ts +239 -0
- package/src/hosts/claude-settings.ts +50 -0
- package/src/hosts/claude-tool-calls.ts +159 -0
- package/src/hosts/claude.ts +511 -0
- package/src/hosts/codex-configuration.ts +85 -0
- package/src/hosts/codex-events.ts +102 -0
- package/src/hosts/codex-native-calls.ts +702 -0
- package/src/hosts/codex-profile.ts +78 -0
- package/src/hosts/codex-skill-reads.ts +345 -0
- package/src/hosts/codex.ts +769 -0
- package/src/hosts/isolation-roots.ts +60 -0
- package/src/hosts/mac-sandbox.ts +108 -0
- package/src/hosts/native-controls.ts +124 -0
- package/src/hosts/protected-worktrees.ts +56 -0
- package/src/hosts/workspace-fingerprint.ts +55 -0
- package/src/identity.ts +156 -0
- package/src/instrumentation.ts +106 -0
- package/src/preparation.ts +211 -0
- package/src/provenance.ts +244 -0
- package/src/report.ts +351 -0
- package/src/repository-fixture.ts +286 -0
- package/src/results.ts +160 -0
- package/src/run-owner.ts +276 -0
- package/src/schema.ts +28 -0
- package/src/storage.ts +23 -0
- package/src/trial-scheduler.ts +27 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Result and evidence contract v1
|
|
2
|
+
|
|
3
|
+
The public CLI accepts `--json`. In that mode stdout contains one JSON result
|
|
4
|
+
document and no progress text; diagnostics go to stderr. Human output names
|
|
5
|
+
the same execution, grading, and task states. Every result names its schema
|
|
6
|
+
version. A run with retained evidence names its absolute evidence path;
|
|
7
|
+
pre-run configuration failures can return `null`.
|
|
8
|
+
Each domain outcome also gets one human-readable line with its case, trial,
|
|
9
|
+
outcome ID, and status. Domain outcomes remain independent of the task verdict
|
|
10
|
+
and exit code.
|
|
11
|
+
|
|
12
|
+
## Separate states
|
|
13
|
+
|
|
14
|
+
Each trial and aggregate result carries:
|
|
15
|
+
|
|
16
|
+
| Field | Values | Meaning |
|
|
17
|
+
| ------------------ | ---------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
18
|
+
| `execution.status` | `completed`, `failed`, `cancelled`, `not_run` | Whether host execution completed. Dry preparation is `not_run`. |
|
|
19
|
+
| `grading.status` | `completed`, `error`, `unavailable`, `not_requested` | Whether required grading completed. A prompt without criteria is `not_requested`. |
|
|
20
|
+
| `task.verdict` | `passed`, `failed`, `not_assessed` | Judgment against declared criteria, independent of process completion. |
|
|
21
|
+
|
|
22
|
+
With successful host execution and no success criteria, the result is
|
|
23
|
+
`completed` / `not_requested` / `not_assessed`. A failed check after successful
|
|
24
|
+
execution is `completed` / `completed` / `failed`. An execution failure,
|
|
25
|
+
grader error, or unavailable required evidence cannot yield `passed`. A dry
|
|
26
|
+
run is `not_run` / `not_requested` / `not_assessed` even when preparation checks
|
|
27
|
+
pass. Missing optional cost or usage remains `null` or explicitly incomplete;
|
|
28
|
+
it is never converted to zero.
|
|
29
|
+
|
|
30
|
+
Each new trial records `candidateDurationMs` from a monotonic clock around the
|
|
31
|
+
candidate host call and observation validation. Dry preparation records `null`;
|
|
32
|
+
older artifacts without this field have unknown duration.
|
|
33
|
+
|
|
34
|
+
For multiple trials, a case applies its declared pass threshold only after all
|
|
35
|
+
required trials are assessed. An unassessed trial makes the case
|
|
36
|
+
`not_assessed`; otherwise its pass rate determines `passed` or `failed`. The
|
|
37
|
+
run verdict is `failed` if any case fails, otherwise `not_assessed` if any case
|
|
38
|
+
is unassessed, otherwise `passed`. A failed run verdict can coexist with an
|
|
39
|
+
execution or grading error from another case. Execution and grading aggregate
|
|
40
|
+
states expose errors or unavailability instead of averaging them away.
|
|
41
|
+
|
|
42
|
+
## Exit codes
|
|
43
|
+
|
|
44
|
+
The CLI uses this precedence when several outcomes occur in one invocation:
|
|
45
|
+
|
|
46
|
+
| Code | Outcome |
|
|
47
|
+
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
48
|
+
| `0` | No execution or grading error and no failed assessment. Includes prompt-only and successful dry runs whose task verdict is `not_assessed`; output distinguishes them from `passed`. |
|
|
49
|
+
| `1` | At least one completed task assessment failed. |
|
|
50
|
+
| `2` | Host execution failed. |
|
|
51
|
+
| `3` | A required grader or extension failed. |
|
|
52
|
+
| `4` | Required evidence was unavailable. |
|
|
53
|
+
| `64` | Invalid invocation or configuration before a run. |
|
|
54
|
+
| `70` | Internal runner or persistence failure. |
|
|
55
|
+
| `130` | Interrupted by SIGINT. |
|
|
56
|
+
| `143` | Interrupted by SIGTERM. |
|
|
57
|
+
|
|
58
|
+
Interruption and internal failure outrank execution failure, which outranks
|
|
59
|
+
grading error, unavailable evidence, and task failure. The exit code is a
|
|
60
|
+
summary; the JSON result retains every affected trial's exact status.
|
|
61
|
+
|
|
62
|
+
## Identity and provenance
|
|
63
|
+
|
|
64
|
+
New retained evidence separately identifies:
|
|
65
|
+
|
|
66
|
+
- the Sevro package name, exact version and build digest, or an explicit local
|
|
67
|
+
checkout revision and dirty-patch digest;
|
|
68
|
+
- the evaluated project's revision and dirty-patch digest, without assuming it
|
|
69
|
+
is the runner checkout;
|
|
70
|
+
- the extension ID, version, source/content digest, configuration digest,
|
|
71
|
+
negotiated protocol and capabilities, active graders, replaced defaults,
|
|
72
|
+
selected task-verdict policy, and requested and applied instrumentation;
|
|
73
|
+
- each candidate, semantic grader, and advisory judge's exact host, model,
|
|
74
|
+
effort, raw-result provenance, and observation completeness; and
|
|
75
|
+
- the declared passive/enforced condition, case inputs, check definitions,
|
|
76
|
+
required evidence, and execution mode.
|
|
77
|
+
|
|
78
|
+
The evaluation identity includes evaluator version and content, configuration,
|
|
79
|
+
grader selection and replacements, required evidence, instrumentation, host
|
|
80
|
+
routes, case inputs, fixture, checks, trial count, and threshold. A comparison
|
|
81
|
+
cannot claim matched conditions when those dimensions differ. Timestamps,
|
|
82
|
+
temporary paths, run IDs, and output locations do not change evaluation
|
|
83
|
+
identity. Historical Darrow artifacts keep their original schema version;
|
|
84
|
+
fields absent from them remain unknown unless explicit historical provenance
|
|
85
|
+
establishes the value.
|
|
86
|
+
The pre-run instrumentation digest binds the requested list and its expected
|
|
87
|
+
application. Trial evidence records the host-reported application; a mismatch
|
|
88
|
+
fails execution and cannot be treated as a matched successful condition.
|
|
89
|
+
When a task-verdict policy is selected, each trial records its recommendation
|
|
90
|
+
separately from the final task verdict. A missing recommendation cannot produce
|
|
91
|
+
a passing assessment.
|
|
92
|
+
An optional advisory review records `completed`, `failed`, or `not_run` with
|
|
93
|
+
its structured assessment, independent usage, and raw-response provenance.
|
|
94
|
+
Its recommendation and any reviewer failure do not change execution, grading,
|
|
95
|
+
task verdict, or exit code. A failure to retain review evidence remains a
|
|
96
|
+
persistence error.
|
|
97
|
+
|
|
98
|
+
[`identity-v1.md`](identity-v1.md) defines the canonical digest and each
|
|
99
|
+
comparison dimension.
|
|
100
|
+
|
|
101
|
+
The versioned machine-readable contracts are
|
|
102
|
+
[`cli-result-v1.schema.json`](../schemas/cli-result-v1.schema.json) and
|
|
103
|
+
[`run-evidence-v1.schema.json`](../schemas/run-evidence-v1.schema.json). A
|
|
104
|
+
schema-valid document still needs engine validation for cross-record equality,
|
|
105
|
+
canonical identity computation, path containment, secret redaction, and
|
|
106
|
+
referenced artifact availability.
|
|
107
|
+
|
|
108
|
+
The engine persists each completed trial atomically before fixture cleanup.
|
|
109
|
+
An interrupted or failed run keeps completed trials plus an explicit partial
|
|
110
|
+
attempt or diagnostic record. Failed persistence is an internal error and
|
|
111
|
+
cannot be presented as a successful assessment.
|
|
112
|
+
|
|
113
|
+
A host adapter can return `executionFailed: true` with bounded artifacts from
|
|
114
|
+
a failed process. The engine retains those artifacts, skips all grading, and
|
|
115
|
+
reports `failed` / `not_requested` / `not_assessed` with exit code `2`. A final
|
|
116
|
+
message that happens to match a check cannot turn that failure into a pass.
|
|
117
|
+
Claude retains its bounded event stream and, when present, up to 64 KiB of
|
|
118
|
+
stderr as private host artifacts. Failure bodies do not appear in CLI diagnostics.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "basic-graded",
|
|
3
|
+
"prompt": "Return ready.",
|
|
4
|
+
"fixture": { "files": { "README.md": "fixture\n" } },
|
|
5
|
+
"checks": [
|
|
6
|
+
{
|
|
7
|
+
"id": "ready",
|
|
8
|
+
"grader": "sevro.regex",
|
|
9
|
+
"configuration": { "pattern": "^ready$" }
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"requiredEvidence": []
|
|
13
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bjoernrochel/sevro",
|
|
3
|
+
"version": "0.1.0-rc.1",
|
|
4
|
+
"license": "BUSL-1.1",
|
|
5
|
+
"description": "A standalone evaluation runner for agentic coding capabilities",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"private": false,
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/BjRo/sevro.git"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"registry": "https://registry.npmjs.org/",
|
|
14
|
+
"access": "public",
|
|
15
|
+
"tag": "next"
|
|
16
|
+
},
|
|
17
|
+
"packageManager": "bun@1.3.13",
|
|
18
|
+
"files": [
|
|
19
|
+
"README.md",
|
|
20
|
+
"docs/",
|
|
21
|
+
"examples/",
|
|
22
|
+
"schemas/",
|
|
23
|
+
"src/"
|
|
24
|
+
],
|
|
25
|
+
"bin": {
|
|
26
|
+
"sevro": "./src/cli.ts"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"cli:dev": "bun src/cli.ts",
|
|
30
|
+
"test": "bun test",
|
|
31
|
+
"test:package-install": "bun scripts/verify-package-install.ts",
|
|
32
|
+
"release:prepare": "bun scripts/prepare-release.ts",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"format:check": "prettier --check README.md docs/*.md examples/**/*.json examples/**/*.ts schemas/*.json src/**/*.ts scripts/**/*.ts tests/**/*.ts package.json tsconfig.json .github/workflows/*.yml"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"ajv": "8.20.0",
|
|
38
|
+
"smol-toml": "1.8.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/bun": "^1.2.0",
|
|
42
|
+
"prettier": "^3.9.9",
|
|
43
|
+
"typescript": "^5.7.0"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:sevro:schema:cli-result:v1",
|
|
4
|
+
"title": "Sevro CLI JSON result v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [
|
|
7
|
+
"format",
|
|
8
|
+
"runId",
|
|
9
|
+
"execution",
|
|
10
|
+
"grading",
|
|
11
|
+
"task",
|
|
12
|
+
"exitCode",
|
|
13
|
+
"evidencePath",
|
|
14
|
+
"cases"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"format": { "const": "sevro.cli-result.v1" },
|
|
18
|
+
"runId": { "type": ["string", "null"] },
|
|
19
|
+
"execution": { "$ref": "#/$defs/execution" },
|
|
20
|
+
"grading": { "$ref": "#/$defs/grading" },
|
|
21
|
+
"task": { "$ref": "#/$defs/task" },
|
|
22
|
+
"exitCode": { "enum": [0, 1, 2, 3, 4, 64, 70, 130, 143] },
|
|
23
|
+
"evidencePath": { "type": ["string", "null"] },
|
|
24
|
+
"cases": { "type": "array", "items": { "$ref": "#/$defs/case" } },
|
|
25
|
+
"diagnostic": { "$ref": "#/$defs/diagnostic" }
|
|
26
|
+
},
|
|
27
|
+
"allOf": [{ "$ref": "#/$defs/stateConsistency" }],
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"$defs": {
|
|
30
|
+
"stateConsistency": {
|
|
31
|
+
"allOf": [
|
|
32
|
+
{
|
|
33
|
+
"if": {
|
|
34
|
+
"properties": {
|
|
35
|
+
"execution": {
|
|
36
|
+
"properties": {
|
|
37
|
+
"status": { "enum": ["failed", "cancelled", "not_run"] }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"then": {
|
|
43
|
+
"properties": {
|
|
44
|
+
"task": {
|
|
45
|
+
"properties": { "verdict": { "not": { "const": "passed" } } }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"if": {
|
|
52
|
+
"properties": {
|
|
53
|
+
"grading": {
|
|
54
|
+
"properties": {
|
|
55
|
+
"status": {
|
|
56
|
+
"enum": ["error", "unavailable", "not_requested"]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"then": {
|
|
63
|
+
"properties": {
|
|
64
|
+
"task": {
|
|
65
|
+
"properties": { "verdict": { "not": { "const": "passed" } } }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"execution": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"required": ["status"],
|
|
75
|
+
"properties": {
|
|
76
|
+
"status": { "enum": ["completed", "failed", "cancelled", "not_run"] },
|
|
77
|
+
"errorCode": { "type": "string", "minLength": 1 }
|
|
78
|
+
},
|
|
79
|
+
"additionalProperties": false
|
|
80
|
+
},
|
|
81
|
+
"grading": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"required": ["status"],
|
|
84
|
+
"properties": {
|
|
85
|
+
"status": {
|
|
86
|
+
"enum": ["completed", "error", "unavailable", "not_requested"]
|
|
87
|
+
},
|
|
88
|
+
"errorCode": { "type": "string", "minLength": 1 }
|
|
89
|
+
},
|
|
90
|
+
"additionalProperties": false
|
|
91
|
+
},
|
|
92
|
+
"task": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"required": ["verdict"],
|
|
95
|
+
"properties": {
|
|
96
|
+
"verdict": { "enum": ["passed", "failed", "not_assessed"] }
|
|
97
|
+
},
|
|
98
|
+
"additionalProperties": false
|
|
99
|
+
},
|
|
100
|
+
"check": {
|
|
101
|
+
"type": "object",
|
|
102
|
+
"required": ["id", "grader", "status"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"id": { "type": "string", "minLength": 1 },
|
|
105
|
+
"grader": { "type": "string", "minLength": 1 },
|
|
106
|
+
"status": { "enum": ["passed", "failed", "unavailable"] },
|
|
107
|
+
"detail": { "type": "string", "maxLength": 4096 },
|
|
108
|
+
"evidenceRefs": {
|
|
109
|
+
"type": "array",
|
|
110
|
+
"items": { "type": "string", "minLength": 1 },
|
|
111
|
+
"uniqueItems": true
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"additionalProperties": false
|
|
115
|
+
},
|
|
116
|
+
"domainOutcome": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"required": ["id", "status", "evidenceRefs"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"id": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"pattern": "^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$",
|
|
123
|
+
"maxLength": 128
|
|
124
|
+
},
|
|
125
|
+
"status": { "enum": ["passed", "failed", "unavailable"] },
|
|
126
|
+
"detail": { "type": "string", "maxLength": 4096 },
|
|
127
|
+
"evidenceRefs": {
|
|
128
|
+
"type": "array",
|
|
129
|
+
"items": { "type": "string", "minLength": 1 },
|
|
130
|
+
"uniqueItems": true
|
|
131
|
+
},
|
|
132
|
+
"data": { "type": "object" }
|
|
133
|
+
},
|
|
134
|
+
"additionalProperties": false
|
|
135
|
+
},
|
|
136
|
+
"trial": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"required": [
|
|
139
|
+
"trial",
|
|
140
|
+
"execution",
|
|
141
|
+
"grading",
|
|
142
|
+
"task",
|
|
143
|
+
"checks",
|
|
144
|
+
"artifactPath"
|
|
145
|
+
],
|
|
146
|
+
"properties": {
|
|
147
|
+
"trial": { "type": "integer", "minimum": 1 },
|
|
148
|
+
"execution": { "$ref": "#/$defs/execution" },
|
|
149
|
+
"grading": { "$ref": "#/$defs/grading" },
|
|
150
|
+
"task": { "$ref": "#/$defs/task" },
|
|
151
|
+
"checks": { "type": "array", "items": { "$ref": "#/$defs/check" } },
|
|
152
|
+
"domainOutcomes": {
|
|
153
|
+
"type": "array",
|
|
154
|
+
"items": { "$ref": "#/$defs/domainOutcome" }
|
|
155
|
+
},
|
|
156
|
+
"artifactPath": { "type": ["string", "null"] }
|
|
157
|
+
},
|
|
158
|
+
"allOf": [{ "$ref": "#/$defs/stateConsistency" }],
|
|
159
|
+
"additionalProperties": false
|
|
160
|
+
},
|
|
161
|
+
"case": {
|
|
162
|
+
"type": "object",
|
|
163
|
+
"required": ["caseId", "execution", "grading", "task", "trials"],
|
|
164
|
+
"properties": {
|
|
165
|
+
"caseId": { "type": "string", "minLength": 1 },
|
|
166
|
+
"execution": { "$ref": "#/$defs/execution" },
|
|
167
|
+
"grading": { "$ref": "#/$defs/grading" },
|
|
168
|
+
"task": { "$ref": "#/$defs/task" },
|
|
169
|
+
"trials": { "type": "array", "items": { "$ref": "#/$defs/trial" } }
|
|
170
|
+
},
|
|
171
|
+
"allOf": [{ "$ref": "#/$defs/stateConsistency" }],
|
|
172
|
+
"additionalProperties": false
|
|
173
|
+
},
|
|
174
|
+
"diagnostic": {
|
|
175
|
+
"type": "object",
|
|
176
|
+
"required": ["code", "message"],
|
|
177
|
+
"properties": {
|
|
178
|
+
"code": { "type": "string", "minLength": 1 },
|
|
179
|
+
"message": { "type": "string", "minLength": 1, "maxLength": 4096 }
|
|
180
|
+
},
|
|
181
|
+
"additionalProperties": false
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|