diff --git a/SCOPE.md b/SCOPE.md index 2dc52d9..6da3b97 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -1,52 +1,121 @@ # SCOPE +> Capability snapshot: 2026-08-23. `INTENT.md` states the destination and +> boundaries; this file records what the repository currently implements and +> has evidence for. + ## One-liner -Claude-Code-CLI-driven rein: governed, unattended/scheduled agent runtime. -Formerly `agent-harness`; renamed per glas-harness ADR-001. Deployed live on -Railiance for tenant `binky-control`. +`rein-aharness` is the Claude-Code-CLI-oriented rein that claims scheduled +Activity Core work, routes versioned execution profiles through Glas, and +retains a legacy set of local task executors for unattended repository work. -## Core Idea +## Implemented capability -The single shared, multi-tenant runtime: consumes tasks (local JSON file or -issue-core polling), loads a kaizen-agentic persona, runs a bounded Claude -Code CLI session under a named tool profile allow-list, verifies a local -commit, reports to State Hub and `.kaizen/metrics`. The harness is the only -credential holder and only policy enforcement point for its sessions. +### Intake and lifecycle -## In Scope +- The primary production intake is the Activity Core `ops_run` REST queue. + The worker filters and claims rows, heartbeats their lease, and completes or + fails them with normalized result data. +- A queued `harness_profile_ref` is authoritative. The worker carries its + allowlisted attribution refs into a Glas `ExecutionRequest`, uses governed + actor `agt`, returns the complete `GatewayResult`, and never falls back to a + legacy approach after profile refusal or failure. +- Profile-absent rows use the coexistence registry in `approaches.py`. + Unmatched rows fail visibly. JSON task files remain available for local + development, and issue-core polling remains as a legacy compatibility path. +- The production claim loop is a single-concurrency user systemd service on + railiance01. Claim failures use the configured poll interval and active runs + receive lease heartbeats. -- Instance manifest resolution (`.kaizen/schedule.yml` extensions), - named tool profiles (`green-commit-only`, `blue-mail-triage`) -- Task intake: local task-file (dev) and issue-core polling (production) -- The agentic session itself (`adapter.py`/`runner.py`), including - per-tool-call audit streaming (`--stream-tool-events`, - `HARNESS-WP-0002-T03`) -- kaizen metrics + State Hub progress/token reporting -- Railiance packaging and deployment (`Containerfile`, `deploy/`) -- Two non-Claude, non-agentic side paths: deterministic mailbox scan - (`mail-scan`) and llm-connect-JSON-driven mail-triage/daily-brief +### Execution paths -## Out of Scope +- Generic local `TaskSpec` runs resolve instance policy, optionally load a + kaizen-agentic persona bundle, invoke Claude Code in the target checkout, + impose a wall-clock timeout and named Claude tool allow-list, and require a + new Git `HEAD` before reporting success. +- Optional Claude stream JSON is reduced to tool/hook audit events and can be + reported to State Hub. +- Versioned profiled rows delegate profile, rein, model, tool, sandbox, and + teardown decisions to Glas/sand-boxer. `rein-aharness` owns the queue + adapter, not the meta-framework or sandbox implementation. +- Legacy structured executors produce Freedom Intelligence daily research + briefs, Binky daily/weekly briefs, deterministic mailbox scans, and mailbox + triage. The LLM-backed structured paths use the llm-connect HTTP service; + mailbox credential acquisition is a bounded OpenBao/AppRole pre-step. +- A deterministic smoke path can clone a controlled sandbox repository, + commit `SMOKE.md`, optionally push it, and report evidence without invoking + Claude. -- Scheduling and blueprint authoring — stay in `activity-core` and - `kaizen-agentic` respectively (this repo only consumes/loads them) -- Being the glas-harness meta-framework itself — this repo is one - concrete rein under it, not the router - (`glas-harness/docs/adr/ADR-001-rein-harness-family.md`) -- LLM provider abstraction — stays in `llm-connect` +### Declarative policy and reporting -## Current State +- `.kaizen/schedule.yml` parsing and validation cover cadence, enabled state, + blueprint name, green/blue lane, named tool profile, token budget, and + harness-major pin. Strict validation requires the runtime fields for enabled + instances. +- The local profile registry contains `green-commit-only` and + `blue-mail-triage`. Unknown profiles fail closed. Both restrict the Claude + session to repository read/edit operations and selected local Git commands; + lane itself is metadata and consistency validation, not an OS security + boundary. +- Runs can append `.kaizen/metrics//executions.jsonl`, regenerate the + summary, emit State Hub progress/tool/token events, and close an associated + Hub task. These reporting operations are best-effort. +- llm-connect HTTP errors retain only bounded, allowlisted provider diagnosis. -`HARNESS-WP-0001` (foundation) and `HARNESS-WP-0002` (rename + glas-harness -alignment, including the live Railiance cutover) are both done. Live-proven -through glas-harness's gateway with a real Claude Code session and a real -verified commit. Deploy artifacts, CLI, and package are all under the -`rein-aharness` name on the live Railiance deployment. +### Packaging and deployment -## Getting Oriented +- The Python package and CLI are version `0.1.0`; Glas and sand-boxer are + optional sibling runtime dependencies. +- The host deployment includes a user-service claim loop and helpers for + resolving in-cluster Activity Core, llm-connect, and State Hub services. +- A container image and hardened Kubernetes manifests exist. The Kubernetes + Deployment currently runs `sleep infinity`; it validates packaging and + image availability but is not the production claim worker. -- Start with: `INTENT.md` -- Deploy: `deploy/README.md` -- Agent instructions: `AGENTS.md` -- Workplans: `workplans/` +## Current evidence and limits + +- The historical 2026-07-26 proof exercised a real Claude CLI session and + commit through the then-current coarse Glas rein contract. The deterministic + Railiance smoke also proved clone, commit, optional push, and Hub reporting. +- The current profiled queue adapter is deployed at `c633291`. Production run + `ededc939-266f-473c-8386-ffd3f027f5f0` proved profile/ref preservation, + governed actor mapping, resolution, normalized failure, and sandbox teardown. + It failed closed at `session_start` before Claude dispatch or commit because + executable bwrap reachability, mounted rein runtime, and model egress remain + with upstream residual `GLAS-IN-0002`. +- Direct legacy agent sessions rely on Claude Code's own tool mediation and + the host checkout. They are not an OS-level sandbox, do not lock the repo, + and do not prove that no push/network activity occurred after the run. +- Commit acceptance currently means only that `HEAD` changed. It does not yet + validate the changed-file set, branch/parent shape, clean working tree, + remote state, or provenance of the new commit. Metrics are written after + this check and can leave target-repo changes for a later commit. +- The worker is sequential and repository mapping is host configuration. There + is no multi-worker repository lease, per-tenant process isolation, generic + credential broker, or tenant onboarding API. +- Freedom Intelligence and Binky approach matching, output formats, event + names, mailbox paths, and one default push behavior are tenant-specific + compatibility code. They are implemented capability, but conflict with the + intended generic-runtime boundary and should not be the pattern for new + tenants. + +## Explicit boundaries + +- Scheduling and activity definitions belong to Activity Core. +- Blueprint authoring and improvement loops belong to kaizen-agentic. +- Profile routing and rein selection belong to Glas. +- Sandbox lifecycle and isolation belong to sand-boxer. +- Provider abstraction belongs to llm-connect. +- Durable work history and decisions belong to State Hub; agent memory and + metrics remain in the consuming repository. + +## Orientation + +- Purpose and target boundaries: `INTENT.md` +- Intent-versus-capability assessment: + `history/2026-08-23-intent-scope-gap-assessment.md` +- Runtime architecture: `docs/architecture.md` +- Production claim loop: `docs/ops-run-claim-loop.md` +- Deployment: `deploy/README.md` +- Completed work records: `workplans/` diff --git a/history/2026-08-23-intent-scope-gap-assessment.md b/history/2026-08-23-intent-scope-gap-assessment.md new file mode 100644 index 0000000..299a193 --- /dev/null +++ b/history/2026-08-23-intent-scope-gap-assessment.md @@ -0,0 +1,128 @@ +# Intent–scope gap assessment — 2026-08-23 + +## Purpose and method + +This assessment compares the commitments and prohibitions in `INTENT.md` +against the repository's source, tests, deployment files, completed workplans, +and the current railiance01 worker. It distinguishes implemented behavior from +historical proof and from the target architecture. It does not treat completed +workplan status as proof that every statement in `INTENT.md` is already true. + +At the time of review there was no actionable repo work: the Custodian brief +listed no active workstream, every file-backed workplan was done or finished, +the repo had no matching human-needed task, and the two unread messages were a +Glas acknowledgement plus a superseded request already delivered in +`c633291`. + +## Overall assessment + +`rein-aharness` is a useful deployed queue consumer and bounded execution +adapter, but it only partially realizes the intended single shared, +multi-tenant agent runtime. The strongest implemented boundary is scheduled +work intake: Activity Core owns scheduling, while this repo claims and closes +execution rows. The strongest current governed-execution behavior is +fail-closed profile routing through Glas. + +The largest gap is that the mature, currently usable paths are a mixture of a +host-local Claude runner and tenant-specific FI/Binky functions. The generic +profiled path cannot yet complete a current production session because its +sandbox execution/runtime/egress contract is unresolved upstream. The repo +therefore should not claim complete multi-tenant isolation, universal +credential custody, or comprehensive post-run policy verification. + +## Intent mapping + +| Intent commitment or boundary | Current evidence | Assessment | +| --- | --- | --- | +| Consume work; do not schedule it | `claim_loop.py` consumes Activity Core `ops_run` rows and contains no scheduler. | Met. | +| Keep blueprint authoring in kaizen-agentic | `persona.py` calls `kaizen-agentic schedule prepare`; this repo does not author blueprints. | Boundary met, but a missing/failed prepare silently falls back to no persona. | +| Let consuming repos declare instances | `manifest.py` validates `.kaizen/schedule.yml` runtime extensions and resolves policy for local agent sessions. | Partial: manifests affect local session policy, but profile-driven runs take their execution constellation from Activity Core/Glas and legacy routing is hard-coded here. | +| Provide one shared multi-tenant runtime | One railiance01 user service can map several repository slugs and processes rows sequentially. | Partial: shared process exists, but there is no tenant registry/API, per-tenant process boundary, repository lease, concurrency control, or safe multi-worker coordination. | +| Consume Activity Core tasks | Claim, heartbeat, complete, fail/reopen, label filtering, and configured backoff are implemented and tested. | Met for the REST queue contract. Issue-core remains legacy compatibility. | +| Run bounded sessions through llm-connect | The direct Claude adapter implements llm-connect interfaces with timeout/tool profile/budget hooks; structured executors call llm-connect HTTP. Profiled work delegates the rein/model choice through Glas. | Partial: Claude usage metadata is not demonstrated as accurate token accounting, and the current profiled production route stops before dispatch. | +| Enforce named tool profiles and grants | Unknown profiles refuse; Claude receives a named `--allowedTools` set and a cwd-pinned prompt. Glas profiles are authoritative for profiled rows. | Partial: lane is advisory, direct runs are host-local, and there is no post-run proof of network/push absence, changed-file scope, or clean repository state. | +| Be the only credential holder and policy enforcement point | Mail scan acquires IMAP credentials through an AppRole lane; worker/provider tokens arrive through host environment; Glas and sand-boxer own profile and isolation enforcement. | Not literally met. Credential and enforcement ownership is distributed across the worker, llm-connect, Glas, sand-boxer, OpenBao, and deployment environment. `INTENT.md` should eventually describe the governed chain rather than a single holder if this architecture is retained. | +| Verify a local commit | `runner.py` compares `HEAD` before and after; structured paths stage named output files and commit them. | Partial: a `HEAD` delta is not full verification. There is no repo lock, clean-tree gate, parent/branch check, changed-file allow-list, author/provenance check, or remote/push audit. Metrics are written after the accepted `HEAD` snapshot. | +| Report to State Hub and kaizen metrics | Progress, tool events, token events, task close, JSONL execution metrics, and summaries exist. | Implemented best-effort. Reporting failures are swallowed, so delivery is not part of success acceptance and there is no durable outbox here. | +| Remain generic, not a per-project logic container | The profiled queue adapter and local `TaskSpec` runner are generic. | Diverged in the coexistence path: FI research, Binky briefs, mailbox configuration, event names, label matching, and default FI push behavior are tenant-specific code. | +| Not become an LLM abstraction | Provider selection and HTTP abstraction remain in llm-connect; versioned constellation selection remains in Glas. | Mostly met. The Claude-Code specialization is appropriate rein behavior, though it directly constructs CLI invocation policy. | +| Not become a state store | Durable run/task history is external; only repo-owned `.kaizen/metrics` is written locally. | Met. Local sand-boxer state belongs to the sibling package, not this repo. | +| Be workstation-independent | The claim worker is active on railiance01 and accesses cluster services without a long-lived port-forward. | Met for queue consumption and legacy structured work. Not yet met for a current isolated profiled Claude run; the Kubernetes Deployment is also only a sleeper placeholder. | + +## Gaps requiring future work records + +No new rein-aharness workplan was opened by this documentation audit. The +following are gaps, not implicitly authorized implementation tasks. They should +be triaged into explicit work records before code changes. + +### 1. Complete the generic profiled execution chain + +Current production evidence resolves the requested profile and creates and +destroys the sandbox, but fails at Glas `session_start`. Existing residual +`GLAS-IN-0002` owns executable bwrap reachability, runtime mounting, and model +egress/credential delivery. After that owner contract lands, this repo needs a +fresh bounded Activity Core proof showing dispatch, an accepted commit, full +normalized evidence, and teardown under the current contracts. + +### 2. Replace weak commit acceptance with repository-boundary verification + +Before a direct run, record a clean/dirty baseline and acquire a per-repository +lease. After execution, verify the new commit's parent, changed paths, author +and task correlation, working-tree state, and remote/push state. Decide how +`.kaizen/metrics` joins the commit or moves to a separate evidence write so a +successful run does not create unexplained dirtiness after verification. + +### 3. Retire tenant-specific runtime code + +Move FI/Binky prompt formats, paths, approach matching, completion event names, +mailbox configuration, and push policy into tenant-owned blueprints/manifests +or explicit external capabilities. Until migration, label these functions as a +legacy coexistence surface and do not add another tenant by adding another +branch to `approaches.py`. + +### 4. Reconcile credential and enforcement ownership language + +The implementation is a governed chain, not a single credential holder. Define +which component obtains, injects, observes, and revokes each credential class; +which component enforces tool, filesystem, network, model, and repository +policy; and which evidence proves those controls. Then update `INTENT.md` only +through an explicit architecture decision if “only holder/only enforcement +point” is no longer the desired topology. + +### 5. Make deployment match the runtime claim + +The active worker is the railiance01 user service. The Kubernetes Deployment +only sleeps and the image does not package the optional Glas/sand-boxer +constellation. Either make Kubernetes a real supported claim worker with +workspace, credentials, runtime, and shutdown semantics, or clearly retire it +to an image-smoke artifact. Add a repeatable host prerequisite check for the +bubblewrap/AppArmor policy if the local profile remains supported. + +### 6. Strengthen durability, concurrency, and conformance + +Add repository locking or owner leases, defined recovery after lease loss or +close failure, durable/reporting reconciliation, package-level contract tests +that do not silently skip optional runtimes, and CI/release gates for the +manifest/profile/rein contracts. A single sequential process is safe only +while deployment topology remains singular and target repos do not overlap. + +## Recommended sequencing + +1. Let `GLAS-IN-0002` deliver an executable sandbox contract and re-prove one + current profiled run end to end. +2. Harden repository acceptance and metrics atomicity before increasing worker + concurrency or onboarding more tenants. +3. Extract FI/Binky compatibility logic into owned declarative capabilities. +4. Reconcile credential/policy ownership in an ADR, then align deployment and + `INTENT.md` terminology with that decision. +5. Add CI and conformance gates before declaring the rein generally + multi-tenant. + +## Conclusion + +The implemented product is narrower than the former `SCOPE.md` claimed: a +deployed sequential Activity Core consumer with a generic queue-to-Glas +adapter, a host-local Claude task runner, and several proven legacy structured +executors. That is a coherent and useful v0.1 capability. It is not yet the +fully isolated, credential-centralizing, tenant-neutral runtime described by +`INTENT.md`; the revised `SCOPE.md` now makes that distinction explicit.