plan: define first local profile acceptance and runtime blockers
All checks were successful
ci / validate (push) Successful in 1m17s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
This commit is contained in:
tegwick 2026-09-05 19:23:50 +02:00
parent 74e8fd8aac
commit 97daba45dd
8 changed files with 379 additions and 8 deletions

View file

@ -43,11 +43,11 @@ installs the package, runs the suite, and validates the packaged catalog.
| Profile/catalog resolution | Implemented and CI-validated |
| Unknown, invalid, or known-blocked profile refusal | Implemented before sandbox creation |
| Sandbox create/destroy lifecycle | Implemented; live failure paths prove teardown |
| Original-checkout isolation | Enforced by code: it is never a post-create execution fallback |
| Original-checkout isolation | Non-secret owner-execution proof passed: source absent, mutation refused, sandbox-only commit and complete cleanup |
| SSH transport construction | Implemented and unit-tested; no current positive post-hardening live proof |
| Same-host bwrap execution | Fail-closed, not operational: both local profiles are declared `blocked` and refused before creation; the underlying proof found consumer `nsenter` denied and no in-sandbox rein runtime |
| Same-host bwrap execution | Owner-mediated boundary and stdin task cleanup are live-proven; both local profiles remain `blocked` pending runtime, credential delivery, and explicit egress acceptance |
| `rein-aharness` adapter | Implemented; local selection is blocked before creation, while the remote profile remains an explicitly labeled unverified proof path |
| `rein-openweights` adapter | Implemented; provider credential repair was proven, but current local sandbox execution has the same unresolved owner boundary |
| `rein-openweights` adapter | Implemented; provider credential repair was proven, but current local selection remains blocked pending its runtime, credential, and egress acceptance |
| CLI channel | Implemented |
| State Hub evidence | Implemented as compact progress evidence, not a complete session/tool audit service |
@ -97,9 +97,10 @@ yet Coulomb's general-purpose agent harness service.
## Active gaps
- `GLAS-WP-0005-T05` / `GLAS-IN-0002`: sand-boxer-owned executable bwrap
reachability, rein runtime availability, explicit egress, and credential
delivery are required for a positive in-sandbox rein proof.
- `GLAS-WP-0012` / `GLAS-IN-0002`: prove the first local rein runtime,
governed credential delivery, and explicit egress through the completed
owner-execution adapter. The open-weight portion remains a separate live
requirement in `GLAS-IN-0002`. See `docs/local-profile-acceptance.md`.
- `GLAS-IN-0003`: grandfather the pre-canon `GLAS-0001` identifiers.
- `GLAS-IN-0004`: align the documented ad hoc workplan convention with the
identifier canon.

View file

@ -19,6 +19,7 @@
| workplan | GLAS-WP-0009 | finished | — | workplans/GLAS-WP-0009-operational-handoff-truth.md |
| workplan | GLAS-WP-0010 | finished | — | workplans/GLAS-WP-0010-transport-and-resolution-hardening.md |
| workplan | GLAS-WP-0011 | finished | — | workplans/GLAS-WP-0011-statehub-bootstrap.md |
| workplan | GLAS-WP-0012 | blocked | — | workplans/GLAS-WP-0012-first-local-profile-production-proof.md |
| task | GLAS-WP-0001-T01 | done | — | workplans/GLAS-WP-0001-harness-router-foundation.md |
| task | GLAS-WP-0001-T02 | done | — | workplans/GLAS-WP-0001-harness-router-foundation.md |
| task | GLAS-WP-0001-T03 | done | — | workplans/GLAS-WP-0001-harness-router-foundation.md |
@ -60,6 +61,11 @@
| task | GLAS-WP-0011-T01 | done | — | workplans/GLAS-WP-0011-statehub-bootstrap.md |
| task | GLAS-WP-0011-T02 | done | — | workplans/GLAS-WP-0011-statehub-bootstrap.md |
| task | GLAS-WP-0011-T03 | done | — | workplans/GLAS-WP-0011-statehub-bootstrap.md |
| task | GLAS-WP-0012-T01 | done | — | workplans/GLAS-WP-0012-first-local-profile-production-proof.md |
| task | GLAS-WP-0012-T02 | wait | — | workplans/GLAS-WP-0012-first-local-profile-production-proof.md |
| task | GLAS-WP-0012-T03 | wait | — | workplans/GLAS-WP-0012-first-local-profile-production-proof.md |
| task | GLAS-WP-0012-T04 | wait | — | workplans/GLAS-WP-0012-first-local-profile-production-proof.md |
| task | GLAS-WP-0012-T05 | wait | — | workplans/GLAS-WP-0012-first-local-profile-production-proof.md |
| intake | GLAS-IN-0001 | done | blue | docs/intakes/residuals.md |
| intake | GLAS-IN-0002 | todo | red | docs/intakes/residuals.md |
| intake | GLAS-IN-0003 | todo | green | docs/intakes/residuals.md |

View file

@ -93,6 +93,13 @@ description: |
does not satisfy this production acceptance. GLAS-WP-0005 can close its
boundary-hardening scope with this registered live residual still open.
GLAS-WP-0012 now tracks the first (Claude) local-profile acceptance, starting
from harness.agent-dev-local@1.0.0. Its owner return contract and baseline
are in docs/local-profile-acceptance.md. The corresponding owner dependency
is SAND-WP-0014-T05; its current OpenRouter credential requirement does not
establish the Claude route. Keep this intake open for the open-weight
profile even after the first Claude profile is proven.
Done when a non-secret probe and one real rein command execute inside the
namespace, the source checkout is not visible/mutable, required egress is
explicit, and teardown removes the sandbox workspace.

View file

@ -0,0 +1,125 @@
# First local profile: runtime requirements and acceptance
Work record: [GLAS-WP-0012](../workplans/GLAS-WP-0012-first-local-profile-production-proof.md).
Live residual: `GLAS-IN-0002`. Owner dependency: `SAND-WP-0014-T05`.
Start from `harness.agent-dev-local@1.0.0`: rein-aharness / Claude Code /
`claude-sonnet-4-6` / `green-commit-only`. The future proof candidate is
`harness.agent-dev-local@1.1.0`; it is not yet in the catalog because its runtime,
sandbox profile, and credential route are not resolved.
## Reviewed baseline, 2026-09-05
Glas owner adapter: `63a7f9f`. Sand-boxer:
`b6655d88590e03820675719d6dd574e5f5a9f82e`. Rein-aharness source:
`1429db5ad4c83331b6375349ffde1eb13af9575b`.
Run `.venv/bin/python scripts/inspect-local-runtime.py` to inspect the current
`profile.bwrap-local` from inside owner-mediated execution. This is a
non-secret inventory, not a model call or a readiness bypass. It does not read
credentials or the interactive user's authentication files. Exit zero means
the inventory ran and cleaned up; it does not mean the profile is ready.
Recorded run: sandbox `236f3683`, consumer `agt` / `glas-runtime-baseline`,
run id `glas-wp-0012-baseline`. Inventory completed successfully; final state
was `destroyed` and the workspace was absent.
| Requirement | Current evidence | Required owner deliverable |
|---|---|---|
| Owner execution | Real gateway boundary proof passed in GLAS-WP-0005 | Retain exact identity, argv/stdin, timeout, and teardown semantics |
| Rein runtime | `rein-aharness`, `rein_aharness`, and `llm_connect` absent from sandbox discovery | Read-only, reproducible runtime with all required Python dependencies and working CLI entrypoint |
| Claude runtime | `claude` discoverable; startup/authentication not tested | Pin runtime version; prove startup, model selection, tools, and streaming options under the owner environment |
| Persona preparation | `kaizen-agentic` absent | Explicitly accept the rein's recorded `persona_source=none` for this fixture, or provide the optional runtime |
| Authentication | Selected Glas profile declares no credential route | Claude-compatible value-free route id, owner approval/implementation, delivery and revocation behavior |
| Network | `default: deny`, empty egress, only `lo` | Explicit enforced provider route, required DNS/TLS support, denied-destination proof |
| Writable runtime state | Owner sets `HOME` to the copied worktree | Define private auth/cache/state locations and ensure they cannot enter an agent commit |
The `SANDBOXER_CREDENTIAL_ROUTE_REFS` environment field only carries route
labels. In the reviewed broker it does not acquire or deliver credentials.
Glas must not invent a route id, borrow an interactive login, or use the
OpenRouter credential as a substitute for the selected Claude route.
The bwrap implementation unconditionally creates an isolated network namespace
and does not create an outbound interface. Declaring an egress hostname in YAML
alone cannot make the current runtime reach it. Sand-boxer owns the enforcement
implementation and its negative tests.
The rein uses `llm_connect.claude_code.ClaudeCodeAdapter` and launches Claude
with cwd pinned to the sandbox and a named tool allow-list. Host environment
overrides do not survive the owner's sanitized child environment. The runtime
must work under that actual environment, including Git author configuration,
private writable state, and the applicable tool/streaming CLI options.
## Owner return contract
Record exact non-secret artifact/revision references for:
1. The installed sandbox owner path and host. Glas currently calls the local
creating `SandboxManager`; if the intended deployment requires authenticated
HTTP instead, supply that contract and adapt/prove the client before claiming
equivalence with the local manager proof.
2. The sandbox profile and read-only rein/Claude runtime artifact, Python
dependencies, trust store, executable paths, and writable state placement.
3. The Claude-compatible credential route, delivering component, consumer scope,
and cleanup/revocation behavior. Evidence contains route ids and outcomes,
never values, auth files, or provider responses.
4. The enforced egress destinations and ports, DNS/TLS requirements, and proof
that an undeclared destination remains denied. Provider connectivity does
not grant the agent additional network tools.
5. Non-secret startup checks (`rein-aharness --help`, `claude --version` or
owner-equivalent checks), exact actor/project/run identity, absent source
checkout, and destroyed/absent workspace under the deployed path.
The current SAND-WP-0014-T05 text mentions an OpenRouter AppRole read. That is
a separate route from the chosen first Claude profile. Resolve this distinction
in owner work before selecting credentials or treating T02 as complete.
## Real acceptance fixture
After owner dependencies pass, review the exact versioned candidate as
`unverified` and run it on a disposable repository with no push remote. Use a
local test Git identity and a small non-secret task: create only `PROOF.md`
with a fixed expected line and make exactly one local commit. Bound the run
within the reviewed profile's token/time limits.
Use the actual Glas gateway, concrete `ReinAharness` adapter, installed
`rein-aharness` CLI, and selected Claude model. The GLAS-WP-0005 deterministic
dispatch cannot substitute for this test.
Before teardown, validate through owner execution:
- The expected file content, exactly one new commit, expected changed paths,
and a clean working tree.
- Host source path absent from the sandbox; the source sentinel and Git HEAD
remain unchanged when independently checked on the host.
- Exact actor/project/request id as `consumer.run_id` at create and exec;
declared credential route and network policy match the reviewed candidate.
- No task/auth/cache artifacts in the accepted commit; generated task removed
before destroy, followed by destroyed state and absent workspace.
Retain actual commit/content-validation results before gateway teardown
destroys the workspace. A returned commit SHA alone is insufficient artifact
verification. Keep the proof observer in the acceptance fixture unless a
separate product requirement justifies a general artifact API.
Also retain failed-run cleanup evidence for an unavailable runtime, refused
credential route, denied required egress, and timeout. Use owner-controlled
negative fixtures; do not disable host networking or mutate real credentials.
The current Glas adapter supplies `--no-metrics` and has no repository-grant
field. Rein-aharness explicitly refuses repository-grant runs with
`--no-metrics`. This proof therefore validates its disposable output
independently; it must not claim that the repository-grant contract was exercised.
Production grant propagation, if required by the owner return contract, needs
an explicit adapter/state-storage design before the proof candidate can pass.
## Readiness and rollback
Only the proven candidate becomes `ready`, with evidence recording the exact
host/runtime scope and revisions. A ready catalog entry is not a live health
probe for every host. Preserve the blocked `1.0.0` version as the rollback pin;
returning to it must refuse, never invoke another runtime. Do not silently
retarget existing consumers or enable production schedules.
The open-weight profile remains blocked until its own route and real-rein
proof pass. Keep that portion of `GLAS-IN-0002` live after this workplan closes.

View file

@ -4,7 +4,7 @@ contract_version: "1.0"
status: enabled
operational_readiness:
status: blocked
reason: sand-boxer owner-mediated bwrap execution and in-sandbox rein runtime are unavailable
reason: in-sandbox rein runtime, governed credential delivery, and explicit provider egress are not yet verified
owner: sand-boxer
evidence_ref: GLAS-IN-0002
rein:

View file

@ -4,7 +4,7 @@ contract_version: "1.0"
status: enabled
operational_readiness:
status: blocked
reason: sand-boxer owner-mediated bwrap execution and in-sandbox rein runtime are unavailable
reason: in-sandbox rein runtime, governed credential delivery, and explicit provider egress are not yet verified
owner: sand-boxer
evidence_ref: GLAS-IN-0002
rein:

View file

@ -0,0 +1,72 @@
"""Report non-secret runtime availability inside the existing bwrap profile.
This diagnostic uses owner execution, never runs a model, and does not change
profile readiness. Command discovery does not prove runtime or authentication
health. Run with .venv/bin/python scripts/inspect-local-runtime.py.
"""
import json
import tempfile
from pathlib import Path
from sandboxer.core.manager import SandboxManager
from sandboxer.lifecycle.store import SandboxStore
from sandboxer.models import Consumer, SandboxCreateRequest, SandboxExecRequest
from sandboxer.payments.credits import CreditsStore
from sandboxer.snapshots.store import SnapshotStore
PROBE = """
import importlib.util, json, os, shutil
from pathlib import Path
print(json.dumps({
'commands': {name: shutil.which(name) is not None for name in
['python3', 'git', 'rein-aharness', 'claude', 'kaizen-agentic']},
'python_modules': {name: importlib.util.find_spec(name) is not None
for name in ['rein_aharness', 'llm_connect']},
'interfaces': [line.split(':', 1)[0].strip()
for line in Path('/proc/net/dev').read_text().splitlines()[2:]],
'credential_route_refs': json.loads(os.environ['SANDBOXER_CREDENTIAL_ROUTE_REFS']),
'home_is_workspace': os.environ['HOME'] == str(Path.cwd()),
}))
"""
def main():
with tempfile.TemporaryDirectory(prefix="glas-runtime-baseline-") as temp:
root = Path(temp)
source = root / "source"
source.mkdir()
manager = SandboxManager(
store=SandboxStore(path=root / "sandboxes.json"),
credits=CreditsStore(path=root / "credits.json"),
snapshots=SnapshotStore(path=root / "snapshots.json"),
)
consumer = Consumer(actor="agt", project="glas-runtime-baseline",
run_id="glas-wp-0012-baseline")
status = manager.create(SandboxCreateRequest(
profile="profile.bwrap-local", inputs={"repo": str(source)},
consumer=consumer, ttl="5m",
))
try:
result = manager.execute(status.sandbox_id, SandboxExecRequest(
command=["/usr/bin/python3", "-c", PROBE], consumer=consumer,
timeout_seconds=15,
))
if result.exit_code or result.timed_out or result.output_truncated:
raise RuntimeError("runtime inventory probe failed")
facts = json.loads(result.stdout)
finally:
destroyed = manager.destroy(status.sandbox_id)
removed = not Path(status.reachability.workspace_dir).exists()
facts.update(
sandbox_id=status.sandbox_id, workspace_removed=removed,
state=destroyed.state.value, network_default=result.network_default,
network_egress=result.network_egress,
)
print(json.dumps(facts, indent=2))
return 0 if removed and destroyed.state.value == "destroyed" else 1
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,160 @@
---
id: GLAS-WP-0012
type: workplan
title: "Prove the first local rein profile end to end"
domain: infotech
repo: glas-harness
status: blocked
owner: codex
topic_slug: first-local-profile-production-proof
created: "2026-09-05"
updated: "2026-09-05"
state_hub_workstream_id: "170bf1ae-337f-5553-8d1e-03b07100e08f"
---
# Prove the first local rein profile end to end
## Context and scope
Follow up the Claude-route portion of live residual `GLAS-IN-0002`, originating
in finished `GLAS-WP-0005`. Boundary hardening is committed at `63a7f9f` and
proved with a deterministic non-secret dispatch. That proof did not execute
the real rein CLI or make a model call.
Start from `harness.agent-dev-local@1.0.0` (rein-aharness,
`claude-sonnet-4-6`, `claude-code-cli`, `green-commit-only`). Review a new
versioned candidate after the owner runtime contract is available. Keep the
existing blocked selection as the rollback pin. The open-weight profile and
remote profile do not acquire readiness from this workplan.
Glas owns profile selection, its adapter, and acceptance evidence. Sand-boxer
owns runtime provisioning, execution environment, isolation, egress enforcement,
and teardown. The selected rein and credential owner own authentication and
credential acquisition. Use existing owner work `SAND-WP-0014-T05`; its current
OpenRouter dependency must be distinguished from this first Claude-route proof.
## Establish the exact local baseline and acceptance requirements
```task
id: GLAS-WP-0012-T01
status: done
priority: high
state_hub_task_id: "711aeb7e-4664-5078-8c65-3fe6f46f7999"
```
Completed 2026-09-05. Reviewed Glas `63a7f9f`, sand-boxer `b6655d8`, and
rein-aharness `1429db5`. Added a reproducible non-secret owner-execution runtime
inventory and the [acceptance contract](../docs/local-profile-acceptance.md).
The baseline can discover Python, Git, and a `claude` command. It cannot
discover `rein-aharness`, its Python module, or `llm_connect`. Command discovery
alone does not prove that Claude can start or authenticate. The namespace has
only loopback; declared egress and credential route references are empty.
Owner execution and workspace teardown pass. The baseline is therefore
insufficient for a real rein run.
Reviewed the plan against current implementation. Local preparation is done;
remaining execution waits on the owner inputs in T02.
## Resolve and verify the owner runtime, credential, and egress contract
```task
id: GLAS-WP-0012-T02
status: wait
priority: high
state_hub_task_id: "4209f564-a9ee-57f9-9522-3708988801ef"
```
Dependency: sand-boxer `SAND-WP-0014-T05`, with rein-aharness and its credential
owner. Required deliverables are listed in `docs/local-profile-acceptance.md`:
- Exact runtime artifact/revision, in-sandbox entrypoints and dependencies,
sanitized environment, private writable state, and deployment/host identity.
- A Claude-compatible catalog credential route and owner implementation that
delivers it to the selected runtime. An environment label containing route
references is not credential delivery.
- An owner-defined sandbox profile with explicit enforced provider egress,
DNS/TLS requirements, and negative egress tests. Editing an egress list alone
does not provide connectivity in the current loopback-only implementation.
- Non-secret startup, identity, source-absence, and cleanup evidence through
the same manager/service path the gateway will use.
Done when these deliverables exist at reviewable revisions and their owner
proofs pass. No rein installation in the source checkout, host home mount,
credential injection from the interactive shell, or unrestricted network
substitution is an acceptance path.
## Review and validate the versioned Glas proof candidate
```task
id: GLAS-WP-0012-T03
status: wait
priority: high
state_hub_task_id: "c660808a-1724-555c-bc59-7318870d3591"
```
Depends on T02. Prepare `harness.agent-dev-local@1.1.0` only once the real
sandbox profile and credential route are known. Keep the rein/model route and
tool profile explicit; choose bounded proof limits no greater than the current
900 seconds / 60,000 tokens. Record runtime and sandbox revisions and the
validated host scope in evidence. Account for dependency versions that are not
represented directly in the Glas profile schema.
Use `unverified` only after known blockers are resolved, to label the bounded
real proof. Validate schema, capabilities, route propagation, timeout behavior,
and refusal of the old blocked version. Version coexistence must make an
unversioned selection ambiguous rather than silently changing consumers.
Done when the exact candidate resolves, the real runtime starts through its
owner, the focused tests and full suite pass, and rollback to the blocked
`harness.agent-dev-local@1.0.0` pin is documented.
## Prove one real bounded rein task inside the sandbox
```task
id: GLAS-WP-0012-T04
status: wait
priority: high
state_hub_task_id: "3e791432-8f37-54bd-a44a-55eeff11ac19"
```
Depends on T03. Run the actual `ReinAharness` adapter and installed
`rein-aharness` CLI with Claude through the candidate profile on a disposable
Git fixture. Do not substitute deterministic dispatch or change the source
checkout to satisfy the task. Verify the acceptance assertions in the contract,
including exactly one intended commit, a clean final tree, unchanged/inaccessible
host source, exact identity, bounded duration, task cleanup, and destruction.
Collect and validate the sandbox artifact before gateway teardown removes the
workspace. Implement the smallest necessary proof observer in the acceptance
fixture; direct evidence must distinguish actual content validation from a
reported commit SHA. Preserve compact value-free evidence only.
Done when the bounded real run and relevant failure/cleanup checks pass with
the exact selected profile/runtime pins and credential route identified.
## Publish evidence and mark only the proven profile ready
```task
id: GLAS-WP-0012-T05
status: wait
priority: high
state_hub_task_id: "f7635cf6-e044-52d4-8242-0512e0ccbd7b"
```
Depends on T04. Update only the proven candidate to `ready` with evidence that
identifies the host/runtime scope, credential route, egress policy, revisions,
limits, and rollback. Run catalog validation and regression checks. Do not
enable production schedules as a side effect of this proof.
Update `GLAS-IN-0002` with the Claude acceptance result. Keep its open-weight
portion live, or split that remaining work into a separately registered record
before closing the intake. Synchronize work records and log progress. Finish
this workplan only when the first profile is proven and residuals remain live.
## Acceptance
One version-pinned local profile runs its actual rein/model task entirely in
the declared sandbox, produces validated local output, and tears down cleanly.
Its readiness describes the proven runtime scope. Other profile readiness and
consumer schedules remain independently governed.