@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
package/LICENSE ADDED
@@ -0,0 +1,159 @@
1
+ Business Source License 1.1
2
+
3
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
4
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
5
+
6
+ -----------------------------------------------------------------------------
7
+
8
+ Parameters
9
+
10
+ Licensor: Björn Rochel <bjoern@bjro.de>
11
+
12
+ Licensed Work: Sevro — a standalone evaluation runner for coding agents.
13
+ The Licensed Work is (c) 2026 Björn Rochel.
14
+
15
+ Additional Use Grant: You may make production use of the Licensed Work only
16
+ as follows:
17
+
18
+ (a) use within your own organization, for any
19
+ purpose, commercial or non-commercial, provided
20
+ that such use is not Commercial Educational
21
+ Production Use;
22
+
23
+ (b) use while performing professional, consulting,
24
+ or contract services for your own clients,
25
+ provided that those services do not include
26
+ Commercial Educational Production Use;
27
+
28
+ (c) use in preparing or delivering training,
29
+ workshops, courses, talks, presentations, or
30
+ other educational offerings, or in creating or
31
+ publishing blog posts, articles, or other
32
+ educational content, provided that such
33
+ production use is not Commercial Educational
34
+ Production Use;
35
+
36
+ (d) use in research, evaluation, and personal
37
+ projects, provided that such use is not
38
+ Commercial Educational Production Use;
39
+
40
+ provided that such production use does not include
41
+ distributing, selling, sublicensing, hosting, or
42
+ otherwise offering the Licensed Work, or a derivative
43
+ work of the Licensed Work, to third parties as a
44
+ product or service whose principal value is the
45
+ functionality of the Licensed Work.
46
+
47
+ For purposes of this Additional Use Grant,
48
+ "Commercial Educational Production Use" means
49
+ production use of the Licensed Work in preparing,
50
+ delivering, or publishing any educational offering or
51
+ content where you or anyone acting on your behalf:
52
+
53
+ (i) receives or expects to receive, directly or
54
+ indirectly, a fee, compensation, sponsorship, or
55
+ other consideration in connection with it;
56
+
57
+ (ii) supplies it as part of, or uses it to advertise
58
+ or promote, a paid product, service, membership,
59
+ or engagement; or
60
+
61
+ (iii) uses it to generate leads or obtain any other
62
+ direct or indirect commercial benefit.
63
+
64
+ Reasonable reimbursement of expenses alone does not
65
+ constitute Commercial Educational Production Use.
66
+ Commercial Educational Production Use is not included
67
+ in this Additional Use Grant.
68
+
69
+ For clarity, nothing in this Additional Use Grant
70
+ limits the non-production rights granted under the
71
+ Terms below.
72
+
73
+ For clarity, contributing modifications back to the
74
+ Licensed Work, and publishing forks that are
75
+ themselves offered free of charge under this License,
76
+ are permitted.
77
+
78
+ Change Date: Two years from the date on which the applicable
79
+ version of the Licensed Work is first made publicly
80
+ available. The Change Date is determined separately
81
+ for each released version.
82
+
83
+ Change License: Mozilla Public License, version 2.0
84
+
85
+ For information about alternative licensing arrangements for the Licensed Work,
86
+ please contact: bjoern@bjro.de
87
+
88
+ -----------------------------------------------------------------------------
89
+
90
+ Notice
91
+
92
+ Business Source License 1.1
93
+
94
+ Terms
95
+
96
+ The Licensor hereby grants you the right to copy, modify, create derivative
97
+ works, redistribute, and make non-production use of the Licensed Work. The
98
+ Licensor may make an Additional Use Grant, above, permitting limited
99
+ production use.
100
+
101
+ Effective on the Change Date, or the fourth anniversary of the first publicly
102
+ available distribution of a specific version of the Licensed Work under this
103
+ License, whichever comes first, the Licensor hereby grants you rights under
104
+ the terms of the Change License, and the rights granted in the paragraph
105
+ above terminate.
106
+
107
+ If your use of the Licensed Work does not comply with the requirements
108
+ currently in effect as described in this License, you must purchase a
109
+ commercial license from the Licensor, its affiliated entities, or authorized
110
+ resellers, or you must refrain from using the Licensed Work.
111
+
112
+ All copies of the original and modified Licensed Work, and derivative works
113
+ of the Licensed Work, are subject to this License. This License applies
114
+ separately for each version of the Licensed Work and the Change Date may vary
115
+ for each version of the Licensed Work released by Licensor.
116
+
117
+ You must conspicuously display this License on each original or modified copy
118
+ of the Licensed Work. If you receive the Licensed Work in original or
119
+ modified form from a third party, the terms and conditions set forth in this
120
+ License apply to your use of that work.
121
+
122
+ Any use of the Licensed Work in violation of this License will automatically
123
+ terminate your rights under this License for the current and all other
124
+ versions of the Licensed Work.
125
+
126
+ This License does not grant you any right in any trademark or logo of
127
+ Licensor or its affiliates (provided that you may use a trademark or logo of
128
+ Licensor as expressly required by this License).
129
+
130
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
131
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
132
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
133
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
134
+ TITLE.
135
+
136
+ MariaDB hereby grants you permission to use this License's text to license
137
+ your works, and to refer to it using the trademark "Business Source License",
138
+ as long as you comply with the Covenants of Licensor below.
139
+
140
+ Covenants of Licensor
141
+
142
+ In consideration of the right to use this License's text and the "Business
143
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
144
+ other recipients of the licensed work to be provided by Licensor:
145
+
146
+ 1. To specify as the Change License the GPL Version 2.0 or any later version,
147
+ or a license that is compatible with GPL Version 2.0 or a later version,
148
+ where "compatible" means that software provided under the Change License
149
+ can be included in a program with software provided under GPL Version 2.0
150
+ or a later version. Licensor may specify additional Change Licenses
151
+ without limitation.
152
+
153
+ 2. To either: (a) specify an additional grant of rights to use that does not
154
+ impose any additional restriction on the right granted in this License, as
155
+ the Additional Use Grant; or (b) insert the text "None".
156
+
157
+ 3. To specify a Change Date.
158
+
159
+ 4. Not to modify this License in any other way.
package/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # Sevro
2
+
3
+ Sevro is a standalone evaluation runner for agentic coding capabilities. It is
4
+ being extracted from [Darrow](https://github.com/BjRo/darrow/issues/95). This
5
+ checkout runs locally and packs as an installable npm tarball.
6
+ The npm package is `@bjoernrochel/sevro`; its installed command is `sevro`.
7
+
8
+ The public v1 contracts are [the extension protocol](docs/extension-protocol-v1.md)
9
+ and [run results](docs/results-v1.md). Sevro owns these generic interfaces;
10
+ projects own their cases and evaluator policy.
11
+ The [generic report](docs/report-v1.md) summarizes retained public results
12
+ without treating unknown measurements as zero or inferring matched comparisons.
13
+
14
+ Machine-readable contracts live in [`schemas/`](schemas/). Run `bun install`,
15
+ `bun test`, `bun run typecheck`, `bun run format:check`, and
16
+ `bun run test:package-install` to validate the npm tarball locally. The package
17
+ test packs and installs Sevro in a temporary project, then runs the installed
18
+ CLI without a Sevro Git checkout.
19
+
20
+ The [release workflow](docs/releases.md) prepares a versioned artifact with its
21
+ file inventory and checksums, verifies that exact tarball, and documents manual
22
+ publication, trusted publishing, Darrow pinning, updates, and rollback.
23
+
24
+ Sevro uses the owner-selected [Business Source License 1.1](LICENSE), preserving
25
+ Darrow's terms and parameters with Sevro named as the Licensed Work. The first
26
+ local candidate is `0.1.0-rc.1`; publication and Darrow's registry pin remain
27
+ separate steps.
28
+
29
+ [`extension-client.ts`](src/extension-client.ts) validates one request and
30
+ response per extension process and negotiates the v1 protocol. It enforces
31
+ message limits, timeouts, response identity, and process-group cancellation.
32
+
33
+ [`extension-session.ts`](src/extension-session.ts) runs the negotiated
34
+ `resolve`, `prepare`, and `evaluate` methods and checks source stability and
35
+ evidence references. The engine accepts additive extension checks for inline
36
+ cases.
37
+
38
+ [`results.ts`](src/results.ts) reduces checks to separate execution, grading,
39
+ and task states, applies case thresholds, and maps the aggregate to a CLI exit
40
+ category.
41
+ [`identity.ts`](src/identity.ts) computes versioned comparison identities from
42
+ canonical JSON. The [identity contract](docs/identity-v1.md) defines the input
43
+ dimensions.
44
+
45
+ The [built-in output graders](docs/builtin-graders-v1.md) evaluate regex, JSON,
46
+ and inline schema assertions on bounded final-message observations.
47
+
48
+ The [first engine slice](docs/engine-slice.md) executes resolved cases through
49
+ an injected host adapter and retains trial evidence before fixture cleanup.
50
+ The [advisory review fixture](docs/advisory-fixture.md) builds a separate Git
51
+ view of the complete candidate change while withholding evaluator paths.
52
+ The [development CLI](docs/development-cli.md) runs that path with a trusted
53
+ adapter module or the bundled Codex and Claude Code routes and emits a
54
+ machine-readable result.
55
+ The [native control observation](docs/native-controls.md) exposes bounded tool
56
+ labels for extension policy on both Codex and Claude, with explicit completeness.
57
+
58
+ The packaged [basic example](examples/basic/) runs without Darrow or a model
59
+ account. From this checkout, run the graded case with:
60
+
61
+ ```sh
62
+ bun src/cli.ts run --json \
63
+ --case-file "$PWD/examples/basic/graded.json" \
64
+ --adapter-module "$PWD/examples/basic/host.ts" \
65
+ --project-root "$PWD" --results-root /tmp/sevro-basic-results \
66
+ --condition passive --trials 1 --threshold 1
67
+ ```
68
+
69
+ Use `prompt-only.json` in place of `graded.json` to see successful execution
70
+ with `task.verdict: not_assessed`. The package installation check runs both
71
+ cases through the installed CLI, with no Sevro source checkout present.
@@ -0,0 +1,23 @@
1
+ # Advisory review fixture
2
+
3
+ `buildBlindAdvisoryFixture(candidateWorkspace, { baseRevision, excludedPaths })`
4
+ creates a temporary Git workspace for a separate quality reviewer. The caller
5
+ supplies the candidate workspace and its `HEAD` revision from before the host
6
+ ran. The helper starts with that revision, replaces the original Git history
7
+ with one synthetic baseline commit, then applies committed, staged, unstaged,
8
+ and non-ignored untracked candidate changes. The returned directory is owned
9
+ by the caller, which must remove it after review.
10
+
11
+ Root `.agents`, `.claude`, `.codex`, and `.git` paths are withheld from both the
12
+ baseline and the change. `excludedPaths` withholds any additional evaluator
13
+ paths. The review workspace has no remote. The helper rejects escaping or
14
+ broken symlinks and limits Git output, untracked file count, and untracked
15
+ bytes. A failed build removes its temporary directory.
16
+
17
+ `advisoryPrompt` passes the task and deterministic check facts to a separate
18
+ review host. `parseAdvisoryAssessment` accepts one bounded JSON response with a
19
+ pass or fail recommendation, overall score, four dimension scores, strengths,
20
+ weaknesses, and a summary. The engine invokes this route when given an
21
+ `advisoryHost` and a Git fixture. It records the route, response, assessment,
22
+ and usage in trial evidence. A reviewer failure or recommendation never
23
+ changes the task verdict. The development CLI exposes adapter and Codex routes.
@@ -0,0 +1,77 @@
1
+ # Built-in graders v1
2
+
3
+ The first built-in graders inspect a complete, bounded final-message
4
+ observation. The engine compiles evaluator-owned check declarations before host
5
+ execution. A missing or incomplete observation yields `unavailable` for every
6
+ output check; it never passes. A failed assertion yields `failed` while grading
7
+ itself remains `completed`.
8
+
9
+ Each declaration has `{ "id", "grader", "configuration" }`. The supported
10
+ output graders are:
11
+
12
+ | Grader | Configuration | Assessment |
13
+ | -------------- | ------------------------------------------------------------------ | ----------------------------------------------------------- |
14
+ | `sevro.regex` | `pattern` string; optional `negate` boolean and `flags` string | Tests final-message text with multiline matching. |
15
+ | `sevro.json` | Optional RFC 6901 `pointer`, `equals`, `contains`, `exactDocument` | Parses JSON, then checks selected value or an array member. |
16
+ | `sevro.schema` | Inline `schema` object; optional `exactDocument` | Validates the parsed JSON with JSON Schema Draft 2020-12. |
17
+ | `sevro.output` | Optional text, JSON, and schema assertions in one declaration | Retains one outcome for a combined final-message contract. |
18
+
19
+ JSON may be raw or contained in one `json` code fence. `exactDocument` requires
20
+ the whole trimmed message to be that JSON document or fence. `contains` selects
21
+ an array and compares one member against a recursive subset; an object with
22
+ only `$regex` matches a string value. Invalid patterns, pointers, and schemas
23
+ fail preflight. Schema references are resolved only from the inline schema; the
24
+ grader does not read paths supplied by a candidate.
25
+
26
+ `sevro.output` accepts `expectExact`, `expectRegex`, `notRegex`, and regex
27
+ `flags`; `validJson`; an inline `schema`; and `jsonPath` with optional
28
+ `expectJson` or `containsJson`. It checks them in that order: JSON validity,
29
+ schema, selected JSON value, exact text, positive regex, then negative regex.
30
+ `validJson: true` requires the entire trimmed message to be one JSON document
31
+ or fence. Exact text compares the untrimmed final message. A bad declaration
32
+ fails before host execution.
33
+
34
+ The shell-check process runner accepts a bounded evaluator-owned `run` string,
35
+ optional `expectedExitCode` and `timeoutMs`, plus `expectExact`, `expectRegex`,
36
+ `notRegex`, and regex `flags` for stdout. Exact matching removes one final
37
+ newline; regex matching always uses multiline mode. The runner executes with
38
+ `sh -e`. On macOS it runs through the outer sandbox with network access denied,
39
+ a credential-free environment, and caller-declared protected roots. Without a
40
+ stdout assertion, process output is discarded. With one, the runner captures
41
+ at most 1 MiB in memory and retains only its digest and byte length. Oversized
42
+ or invalid UTF-8 output is a grading error.
43
+
44
+ The engine grades `sevro.shell` checks after a completed host turn and retains
45
+ one bounded observation per check. A mismatched exit code or stdout assertion
46
+ fails the task; an isolation, timeout, or process error makes grading
47
+ an error. Callers must supply `shellIsolation.protectedRoots` for any shell
48
+ check. The engine also protects its package source, project, results, user
49
+ home, configured host homes, and active peer fixtures. The caller's list must
50
+ include any other source worktrees or private roots. A peer path already
51
+ canonicalized by the engine remains in the deny profile if that peer is
52
+ removed before the sandbox starts; unverified missing roots still fail.
53
+
54
+ `sevro.git-head` accepts `kind: "changed"`, `"unchanged"`, or
55
+ `"base-ancestor"` for a generated or repository Git fixture. The engine
56
+ captures the fixture's base HEAD before the candidate turn, then compares the
57
+ current HEAD and ancestry after a completed turn. The base stays in runner
58
+ memory, outside candidate control. An invalid declaration or non-Git fixture
59
+ fails preflight. An unreadable or malformed Git state is a grading error. A
60
+ bounded `sevro.observation.git-head` records the base, current revision, and
61
+ ancestry result; checks reference that observation.
62
+
63
+ `sevro.semantic` accepts a single nonempty `proposition` string (at most 8 KiB)
64
+ per check. The operator supplies a separate semantic host route. After a
65
+ complete candidate response, the engine sends the bounded final message and
66
+ all declared propositions to that route in an empty, temporary workspace. It
67
+ requires exactly one `pass` or `fail` verdict with a reason for every declared
68
+ check ID. A failed proposition fails the task. A missing or incomplete candidate
69
+ message makes semantic checks unavailable without calling the semantic host; a
70
+ failed, incomplete, or malformed semantic response makes grading an error.
71
+
72
+ The engine retains the raw semantic response outside the candidate workspace
73
+ as `sevro.semantic.verdicts`, plus per-check observations and any bounded
74
+ artifacts returned by the semantic route. The route identity enters the
75
+ evaluation identity and run evidence. Semantic host usage is retained
76
+ separately from candidate usage. Advisory quality judgments still need a host
77
+ routing implementation.
@@ -0,0 +1,49 @@
1
+ # Cache ownership validation
2
+
3
+ The public CLI's curated Claude runtime no longer supplies repository-specific
4
+ cache variables. Tools select their own defaults under an isolated home in the
5
+ trial's Git metadata. Candidate and shell-check homes are separate; their
6
+ curated UV cache is shared within one trial.
7
+
8
+ ## Test-first trace
9
+
10
+ 1. Red — `bun test tests/cli.test.ts -t "CLI curated Claude runtime leaves repository caches to tools"`:
11
+ the synthetic Claude process rejected the injected `DARROW_CACHE_DIR`;
12
+ the public result recorded failed execution and exit 2 instead of a passed
13
+ task. Product code was unchanged.
14
+ 2. Green — `bun test tests/cli.test.ts -t "CLI curated Claude runtime leaves repository caches to tools"`:
15
+ one test passed after removing that override and placing the curated
16
+ candidate home in Git metadata. An intermediate fixture correction
17
+ canonicalized macOS path aliases before testing containment.
18
+ 3. Red — `bun test tests/cli.test.ts -t "CLI curated shell grading leaves repository caches to tools"`:
19
+ candidate execution completed, but the isolated shell check rejected the
20
+ injected cache override and the public task failed. The shell grader was
21
+ unchanged.
22
+ 4. Green — `bun test tests/cli.test.ts -t "CLI curated shell grading leaves repository caches to tools"`:
23
+ one test passed after removing the shell override. Intermediate test repairs
24
+ corrected the public check status to `passed` and read checks from the
25
+ documented CLI result, rather than a nonexistent evidence field.
26
+
27
+ The two commands remain the literal focused commands for these slices.
28
+ Intermediate fixture/assertion failures are not additional behavior evidence.
29
+ The candidate test supplies an unusable caller cache override and verifies
30
+ that it is absent from the host environment. Both tests write tool-owned cache
31
+ files. The shell test also verifies the curated cache, separate homes, and
32
+ an unchanged Git worktree.
33
+
34
+ ## Final gates
35
+
36
+ - `bun run typecheck`
37
+ - `bun run format:check`
38
+ - `bun test`
39
+ - `bun run test:package-install`
40
+
41
+ The installation gate exercises the same environment migration through the
42
+ installed CLI, synthetic Claude executable, and an isolated shell check, with
43
+ no source Git metadata. Darrow separately runs its installed-package parity
44
+ gate against the exact candidate tarball.
45
+
46
+ These fixtures exercise Sevro's real preparation, execution, shell isolation,
47
+ grading, and package boundary. Claude is synthetic; this is not live model
48
+ evidence or proof of Claude's own sandbox behavior. No release is published by
49
+ these checks.
@@ -0,0 +1,47 @@
1
+ # Claude continuation validation
2
+
3
+ The bundled Claude host now starts and resumes the same UUID-bound native
4
+ session for a declared follow-up prompt. The public CLI regressions use
5
+ synthetic executables and credentials without model calls.
6
+
7
+ Working directory: `/Users/bjro/Sources/sevro`.
8
+
9
+ ## Public CLI slices
10
+
11
+ 1. Red — `lean-ctx -c 'bun test tests/cli.test.ts -t "CLI resumes Claude in the same isolated session and grades its final turn"'`:
12
+ exit `64`, with `selected host does not support continuation`.
13
+ 2. Green — `lean-ctx -c 'bun test tests/cli.test.ts -t "CLI resumes Claude in the same isolated session and grades its final turn"'`:
14
+ one test passed with eight assertions. Both calls use the same native
15
+ session, settings, credentials, model, and effort. The final response passes;
16
+ separate turn artifacts, combined usage, and the workspace boundary remain
17
+ in public evidence. A later guard also confirms exactly one initial and one
18
+ resume launch, bringing this test to nine assertions.
19
+ 3. Red — `lean-ctx -c 'bun test tests/cli.test.ts -t "CLI leaves Claude usage unmeasured when a resumed result belongs to another session"'`:
20
+ foreign-session usage was incorrectly retained as complete with four input
21
+ tokens, six output tokens, and cost `0.03`.
22
+ 4. Green — `lean-ctx -c 'bun test tests/cli.test.ts -t "CLI leaves Claude usage unmeasured when a resumed result belongs to another session"'`:
23
+ one test passed with three assertions. Execution fails, task success is
24
+ unassessed, and unbound token and cost measurements remain unknown.
25
+
26
+ The first test initially omitted the generated fixture's `kind`. Its invalid
27
+ configuration was corrected before the meaningful red above; that setup error
28
+ was not a missing-behavior red.
29
+
30
+ ## Additional guards and final gates
31
+
32
+ Two additional CLI guards passed with 62 assertions. They cover failed,
33
+ missing, foreign, and duplicate native results in either turn, prevent resume
34
+ after an invalid initial result, retain failed event evidence without grading,
35
+ and preserve changed, unmeasured, or incomplete usage observations. They were
36
+ added after implementation, without a test-first claim. One initial assertion
37
+ used the wrong retained-check location; it was corrected to the public CLI
38
+ trial checks.
39
+
40
+ The full `lean-ctx -c 'bun test'` gate passed 210 tests with 1,131 assertions
41
+ across 36 files in 67.67 seconds. Typechecking and formatting passed.
42
+ `lean-ctx -c 'bun run test:package-install'` installed Sevro `0.1.0-dev.0`
43
+ without source Git metadata and passed its public-command checks.
44
+
45
+ These results verify the implementation and deterministic failure boundaries.
46
+ A live continuation and Darrow's installed-package integration are recorded
47
+ separately when observed. This remains an unpublished development version.
@@ -0,0 +1,134 @@
1
+ # Codex host integration
2
+
3
+ The Codex adapter consumes `codex exec --json` as one JSONL turn. The
4
+ `summarizeCodexEvents` parser requires one thread start and a completed turn
5
+ with a zero process exit before reporting completion. Malformed, ambiguous,
6
+ and oversized streams are errors. Missing or invalid final usage remains
7
+ incomplete and is never estimated. The last completed `agent_message` before
8
+ turn completion supplies the bounded final response; missing text stays
9
+ unavailable.
10
+ The bounded JSONL stream is retained per trial as the private
11
+ `sevro.codex.events` host artifact. Its file URL and digest appear in trial
12
+ evidence and are available to extension grading; the stream bytes stay out of
13
+ the run JSON.
14
+ The host also retains a bounded `sevro.codex.skill-reads` observation. It
15
+ records the first verified mounted skill and ordered skill names, without
16
+ commands or skill bodies. A completed direct `cat` of a mounted `SKILL.md`
17
+ counts only when the command output contains that file's exact body. Direct
18
+ `sed -n` pages count after their verified line ranges cover the whole body. An
19
+ exact `cat` wrapped by `lean-ctx -c` is accepted only when its reported output
20
+ still contains the full body; a compressed summary cannot prove the read. An
21
+ attempted indirect, malformed, or incomplete read makes the observation
22
+ partial. This is a host observation; an extension decides what selection means
23
+ for its case.
24
+ The same check accepts skill files below the exact installed plugin roots from
25
+ Codex's installation receipts. It does not infer activation from arbitrary
26
+ files in the private plugin cache.
27
+ The `sevro.codex.native-calls` capability retains allowlisted direct goal and
28
+ agent control calls from the native session bound to the completed thread. Its
29
+ observation contains only call names, namespaces, and source ordinals, plus the
30
+ count of submitted `exec` calls. It also records accepted native subagent
31
+ spawns when one request, host start, and matching result occur in order. That
32
+ receipt contains bounded agent identity, route fields, and source ordinals;
33
+ private task messages, code, and outputs are discarded. An accepted spawn proves
34
+ host acceptance, not the child's role, work, or completion. Duplicate,
35
+ mismatched, or malformed evidence cannot establish acceptance.
36
+ The observation also records the ordered names and namespaces of direct native
37
+ tool calls. For collaboration feedback it includes a bounded target when the
38
+ target is readable. That list lets an extension evaluate parent activity after
39
+ handoff without exposing messages or command input. A partial list cannot
40
+ prove that parent work was absent.
41
+ The observation also retains bounded feedback call targets and whether one
42
+ native tool response was observed for each call. It discards message text and
43
+ response content. A response receipt does not establish that the child acted.
44
+ For a two-turn case, it classifies native feedback messages as plaintext,
45
+ encrypted, or unavailable and records exact equality with the follow-up prompt
46
+ only when plaintext is readable. It retains neither message nor prompt bytes.
47
+
48
+ For a second prompt, `sevro.codex.continuation` retains the last validated
49
+ native-session ordinal before resume. Extensions can compare later call
50
+ ordinals with that boundary without reading private arguments.
51
+ The host also retains separate `sevro.codex.initial-skill-reads` and
52
+ `sevro.codex.follow-up-skill-reads` observations. Each applies the same exact
53
+ mounted-skill read check to one completed turn, so an extension can grade read
54
+ order or a missing repeat read without inferring it from the combined list.
55
+
56
+ It also checks native parent command records for exact mounted skill bodies,
57
+ including sessions with no spawn request. The bounded diagnostic distinguishes
58
+ no read from an incomplete read without claiming skill activation.
59
+ It retains the skill name and native ordinal when verified reads complete a
60
+ whole body. Repeated complete reads produce separate receipts; paged reads
61
+ produce one receipt when their ranges first cover the body. An incomplete
62
+ later reread makes the diagnostic partial. Extensions can compare these
63
+ ordinals with an accepted owner boundary without retaining commands or output.
64
+ For accepted spawns, it also checks up to eight child thread rollouts and
65
+ reports whether each is available, unavailable, ambiguous, or partial, with an
66
+ explicit truncation flag. An available rollout includes bounded diagnostics for
67
+ native child commands: the number of commands and skill read attempts, whether
68
+ the exact mounted `SKILL.md` body was read, and whether the check was complete
69
+ or truncated. A rollout with no read differs from a missing or malformed
70
+ rollout. These diagnostics do not establish skill activation or task completion
71
+ by themselves and retain no child prompt, command, or output.
72
+ An available child rollout also reports whether one nonempty final assistant
73
+ message matches a later native completion event for the same turn. This proves
74
+ a returned turn, not the accuracy of the child's work, and retains no message
75
+ body.
76
+ Each available accepted child rollout also retains up to eight nested spawn
77
+ requests with an explicit `requestsTruncated` flag. A request records bounded
78
+ task name, model, effort, and context-fork fields, whether the host accepted it,
79
+ and, for an accepted request, the child reference and thread. The corresponding
80
+ reader session is classified as available, unavailable, ambiguous, or partial;
81
+ `readerResultStatus` is completed only when a nonempty final answer matches a
82
+ later native completion in that session. Private task and answer text are
83
+ discarded. Extensions interpret task names and decide whether a nested reader
84
+ satisfies their policy.
85
+ The record proves an invocation attempt, not its success. A missing, ambiguous,
86
+ unreadable, oversized, or malformed session is unavailable or partial, so its
87
+ absence cannot prove that a control was unused. Calls made through submitted
88
+ code are not classified by this first observation.
89
+ For an explicitly declared `$plugin:skill`, the host verifies that the installed
90
+ skill exists and that the exact token occurs once in the delivered prompt. A
91
+ completed turn yields `sevro.codex.explicit-invocation` with the owner first and
92
+ verified supporting reads after it. Incomplete reads make that receipt partial.
93
+ The `sevro.codex.repository-invocation` capability supports an explicitly
94
+ declared `$skill` from `.agents/skills/<skill>/SKILL.md`. The host checks that
95
+ the repository mount is a bounded regular file with no symlink components and
96
+ that the token occurs once across the delivered turns. It uses the same
97
+ completed-turn dispatch receipt without wrapping the skill as a plugin.
98
+
99
+ `createCodexHost` copies file-based authentication into a private Codex home
100
+ for one turn. It supplies only explicit environment variables to the parent
101
+ process and uses a runner-generated permission profile for candidate commands.
102
+ When the extension declares a local Codex marketplace, the host verifies its
103
+ manifest contains only the named plugins with local sources, rejects package
104
+ symlinks, and installs it with `codex plugin marketplace add` followed by
105
+ `codex plugin add`. It checks each installation receipt against the private
106
+ plugin cache. Candidate commands can read that cache, while the rest of the
107
+ private Codex home, including authentication and configuration, remains denied.
108
+ It refuses fixture-local `.codex` configuration, unsupported enforced
109
+ conditions, unreadable or oversized auth files, malformed event streams, and
110
+ incomplete turns. The host bounds output and runtime, kills its process group
111
+ on timeout or cancellation, and removes private state after the turn. It is
112
+ available through the engine's injected host interface and the development
113
+ CLI's explicit `--host codex` route. Its protocol and evidence host ID is
114
+ `sevro.host.codex`; `codex` remains the CLI route selector.
115
+
116
+ `prepareMacSandboxCommand` provides the macOS shell-grading boundary. Callers
117
+ provide absolute protected roots and a private state root; the primitive
118
+ canonicalizes them, refuses overlap with the fixture workspace, and creates a
119
+ temporary `sandbox-exec` profile that denies reads and writes. It fails if
120
+ macOS isolation is unavailable. The caller releases the profile after the
121
+ process exits. The runner assembles the same protected-root set for Codex
122
+ candidate commands and shell grading.
123
+
124
+ Codex cannot start its native sandbox inside an outer `sandbox-exec` process
125
+ on this host. Its runner-generated permission profile therefore sets an
126
+ explicit workspace rule, denies all other filesystem roots except minimal
127
+ runtime files and the selected executable's install directories, and
128
+ specifically denies protected roots and the private Codex home. An executable
129
+ inside a protected root is rejected. The profile also disables command
130
+ network access and clears inherited command environment variables. The Codex
131
+ parent can read authentication before it starts sandboxed commands. Tests
132
+ invoke the installed `codex sandbox` CLI to prove fixture access, denied
133
+ source/auth reads, and executable access. The process adapter verifies these
134
+ properties before every turn.
@@ -0,0 +1,86 @@
1
+ # Trial concurrency validation
2
+
3
+ The public CLI preserves the positive `--jobs` contract required by Darrow's
4
+ extraction. Its default is three; the option bounds trials within one case.
5
+ Tests invoke the actual CLI and replace only the external candidate host with
6
+ synthetic adapters. No live model call was made.
7
+
8
+ ## Observed test-first slice
9
+
10
+ Working directory: `/Users/bjro/Sources/sevro`.
11
+
12
+ Red — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI bounds parallel trials and retains ordered isolated evidence"'`:
13
+ exit `64` because the public CLI did not accept `--jobs`.
14
+
15
+ Green — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI bounds parallel trials and retains ordered isolated evidence"'`:
16
+ one test passed with 23 assertions. Five trials reach a peak of two active host
17
+ calls, retain separate workspaces and artifacts, and preserve trial-number order
18
+ in results, run evidence, and checkpoints. Every workspace is removed after
19
+ its trial artifact is retained.
20
+
21
+ The first implementation run reached the concurrency assertions but exposed
22
+ an incorrect temporary-path oracle: macOS canonicalized `/var` to `/private/var`.
23
+ The fixture now uses its canonical root; the original missing-option red remains
24
+ the test-first evidence.
25
+
26
+ ## Additional guards
27
+
28
+ Four post-implementation guards cover cancellation of both active trials without
29
+ starting queued work; persistence failure that retains a completed peer before
30
+ diagnostic finalization and keeps the failed fixture; default three-job and
31
+ explicit serial execution with different configuration identities; and invalid
32
+ job limits before result or state storage is created. The complete file passed
33
+ five tests with 70 assertions. These guards do not claim an observed red.
34
+
35
+ Five prior internal tests require serial host-call order to bind expected trial
36
+ values, or a completed first trial before a later failure or cancellation.
37
+ They now request `jobs: 1` explicitly and retain their original assertions.
38
+ The first three focused repairs passed three tests with 25 assertions.
39
+ The combined command `lean-ctx -c 'bun test tests/engine.test.ts tests/claude-host.test.ts -t "runs trials, applies threshold|host artifacts are retained|host failure retains completed|cancellation retains prior|failed Claude execution"'`
40
+ passed all five serial tests with 51 assertions.
41
+
42
+ Final gates cover the full Sevro suite, types, formatting, installed-package
43
+ verification, and Darrow public-interface parity against the same tarball.
44
+ The bounded independent review retains its exact scope and checks outside the
45
+ repository. Dry or synthetic execution does not prove live-model stability.
46
+
47
+ ## Review repairs
48
+
49
+ The independent review identified future-peer sandbox access, late admission
50
+ shutdown on errors, and cancellation before first admission. Each repair has
51
+ an observed public-CLI red and green in `/Users/bjro/Sources/sevro`.
52
+
53
+ Red — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI retains interruption before admitting its first trial"'`:
54
+ SIGINT returned `70` instead of `130`.
55
+
56
+ Green — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI retains interruption before admitting its first trial"'`:
57
+ one test passed with 20 assertions, covering SIGINT and SIGTERM, no host calls,
58
+ empty trial evidence, retained results, and interrupted ownership. The first
59
+ fixture sent its signal before CLI handlers existed and was corrected before
60
+ the recorded red; that process exit is not red evidence.
61
+
62
+ Red — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI sandbox denies read and write access to later admitted peer fixtures"'`:
63
+ the real macOS sandbox allowed access to the later peer, failing the isolation
64
+ check with task exit `1`.
65
+
66
+ Green — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI sandbox denies read and write access to later admitted peer fixtures"'`:
67
+ one test passed with four assertions. Trial one can use its own fixture while
68
+ its sandbox denies reading and writing trial three's marker; trial three keeps
69
+ the original content. The initial inline fixture produced an unrelated Git
70
+ metadata grading error. Using a declared generated Git fixture established the
71
+ recorded isolation red. Candidate and semantic roots are reserved before
72
+ execution. Peer roots are denied directly without querying Git metadata that
73
+ may still be under preparation.
74
+
75
+ Red — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI closes queued admission when grading fails before advisory retention"'`:
76
+ four candidate calls started instead of two while the failing trial's advisory
77
+ work remained held.
78
+
79
+ Green — `lean-ctx -c 'bun test tests/cli-concurrency.test.ts -t "CLI closes queued admission when grading fails before advisory retention"'`:
80
+ one test passed with eight assertions. A required grader error closes admission
81
+ immediately; both admitted trials and advisory results remain retained.
82
+
83
+ A post-implementation guard also covers an execution failure with an already
84
+ active peer, retained trial artifacts, and completed ownership. It makes no red
85
+ claim. These repairs require fresh checks and verification of the original
86
+ closed finding set before committing.