@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.
Files changed (71) hide show
  1. package/LICENSE +159 -0
  2. package/README.md +71 -0
  3. package/docs/advisory-fixture.md +23 -0
  4. package/docs/builtin-graders-v1.md +77 -0
  5. package/docs/cache-ownership-validation.md +49 -0
  6. package/docs/claude-continuation-validation.md +47 -0
  7. package/docs/codex-host.md +134 -0
  8. package/docs/concurrency-validation.md +86 -0
  9. package/docs/configuration-root-validation.md +70 -0
  10. package/docs/development-cli.md +327 -0
  11. package/docs/engine-slice.md +114 -0
  12. package/docs/extension-protocol-v1.md +292 -0
  13. package/docs/fixture-cleanup-validation.md +70 -0
  14. package/docs/identity-v1.md +65 -0
  15. package/docs/native-controls.md +29 -0
  16. package/docs/releases.md +88 -0
  17. package/docs/report-v1.md +32 -0
  18. package/docs/results-v1.md +118 -0
  19. package/examples/basic/graded.json +13 -0
  20. package/examples/basic/host.ts +8 -0
  21. package/examples/basic/prompt-only.json +7 -0
  22. package/package.json +45 -0
  23. package/schemas/cli-result-v1.schema.json +184 -0
  24. package/schemas/extension-v1.schema.json +659 -0
  25. package/schemas/report-v1.schema.json +164 -0
  26. package/schemas/run-evidence-v1.schema.json +510 -0
  27. package/src/advisory-fixture.ts +282 -0
  28. package/src/advisory.ts +105 -0
  29. package/src/cli.ts +837 -0
  30. package/src/engine.ts +2341 -0
  31. package/src/extension-client.ts +257 -0
  32. package/src/extension-session.ts +335 -0
  33. package/src/fixture-bin.ts +87 -0
  34. package/src/fixture-cleanup.ts +38 -0
  35. package/src/fixture-setup.ts +163 -0
  36. package/src/generated-fixture.ts +220 -0
  37. package/src/git-hooks.ts +63 -0
  38. package/src/graders/git-head.ts +176 -0
  39. package/src/graders/output.ts +359 -0
  40. package/src/graders/semantic.ts +120 -0
  41. package/src/graders/shell.ts +277 -0
  42. package/src/hosts/claude-continuation.ts +94 -0
  43. package/src/hosts/claude-credential.ts +73 -0
  44. package/src/hosts/claude-events.ts +128 -0
  45. package/src/hosts/claude-nested-skills.ts +218 -0
  46. package/src/hosts/claude-repository-invocation.ts +239 -0
  47. package/src/hosts/claude-settings.ts +50 -0
  48. package/src/hosts/claude-tool-calls.ts +159 -0
  49. package/src/hosts/claude.ts +511 -0
  50. package/src/hosts/codex-configuration.ts +85 -0
  51. package/src/hosts/codex-events.ts +102 -0
  52. package/src/hosts/codex-native-calls.ts +702 -0
  53. package/src/hosts/codex-profile.ts +78 -0
  54. package/src/hosts/codex-skill-reads.ts +345 -0
  55. package/src/hosts/codex.ts +769 -0
  56. package/src/hosts/isolation-roots.ts +60 -0
  57. package/src/hosts/mac-sandbox.ts +108 -0
  58. package/src/hosts/native-controls.ts +124 -0
  59. package/src/hosts/protected-worktrees.ts +56 -0
  60. package/src/hosts/workspace-fingerprint.ts +55 -0
  61. package/src/identity.ts +156 -0
  62. package/src/instrumentation.ts +106 -0
  63. package/src/preparation.ts +211 -0
  64. package/src/provenance.ts +244 -0
  65. package/src/report.ts +351 -0
  66. package/src/repository-fixture.ts +286 -0
  67. package/src/results.ts +160 -0
  68. package/src/run-owner.ts +276 -0
  69. package/src/schema.ts +28 -0
  70. package/src/storage.ts +23 -0
  71. 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
+ }
@@ -0,0 +1,8 @@
1
+ export default {
2
+ id: "sevro.host.example",
3
+ model: "deterministic-example",
4
+ effort: "none",
5
+ async run() {
6
+ return { finalMessage: "ready", complete: true };
7
+ },
8
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "id": "basic-prompt-only",
3
+ "prompt": "Return ready.",
4
+ "fixture": { "files": { "README.md": "fixture\n" } },
5
+ "checks": [],
6
+ "requiredEvidence": []
7
+ }
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
+ }