You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build brief: shell-cli — the guarded local operations plane for AI agents
This issue is the architectural source of truth for shell-cli. It supersedes
the original narrow “extract six tools from Colleague” framing while preserving
that extraction as the first compatibility slice.
The repository is currently a green scaffold. Development has not started, so
we will establish the complete boundary before copying implementation.
1. Vision
shell-cli is the guarded local operations plane for AI agents.
Colleague should decide why, when, and which action to take.
shell-cli should provide one place to plan, authorize, execute, observe, and
record the local operation.
That includes more than the six model-facing tools. Files, arbitrary commands,
curated tests, lint, hooks, Git/worktree mechanics, and trusted external CLIs
all eventually need the same operation lifecycle even when their higher-level
semantics stay elsewhere.
shell-cli is not another agent. It contains no model, planner, memory, web
browser, or domain workflow. It is the execution substrate beneath them.
2. The operation is the core abstraction
An operation is any local observation, mutation, process invocation, or
environment lifecycle action.
The boundary is work-affecting I/O, not every internal byte Colleague ever
writes. Runtime-private bookkeeping such as artifacts, trace/flight feeds,
telemetry buffers, caches, and lock files remains with its owning runtime unless
it executes code or touches the target workspace. This prevents shell-cli from
becoming a god-layer around ordinary application internals.
Every operation follows one lifecycle:
flowchart LR
C["Colleague intent"] --> O["Operation"]
O --> P["Policy + preview"]
P --> B["Environment backend"]
B --> E["Result + evidence"]
E --> C
Loading
The pure library contract should be provider-neutral and JSON-serializable:
Colleague already uses worktree + host for work/drive and parallel
children. Interactive sessions run checkout + host, and failed worktree
creation may degrade to in-place execution. shell-cli must preserve those
behaviours during migration rather than rebuilding a simpler competing
worktree system.
An environment therefore distinguishes at least:
source_root: trusted repository/control context
work_root: the tree operations may observe/change
runner: host/container implementation
read-only paths
mount policy
network policy
environment-variable and secret policy
user identity, resource limits, and timeout defaults
Policy is snapshotted from trusted control context before model mutations; an
agent must not be able to edit its own active authorization by changing a file
inside the work root.
4. Three operation profiles
Every subprocess must declare why it is running. Avoid treating all subprocess.run calls as equally trusted.
project
Executes repository-controlled code:
model-issued shell commands
tests
lint/format tools
affected-test runners
repository hooks when configured as project code
Target: containerized by default, network disabled unless explicitly granted.
control
Executes trusted agent/control-plane programs:
git worktree/handoff mechanics
devague, eidetic, culture, and coherence CLIs
neighbour clone management
Docker/Podman itself when materializing a container runner
Host execution is expected, but it should use argv vectors, executable
allow-lists, minimal environment inheritance, explicit cwd, bounded output, and
evidence. Raw shell strings are not appropriate for control operations.
observe
Structured reads such as file listing, text/media loading, status, and diff.
These are confined to the selected root and never imply process isolation.
5. Where every Colleague operation goes
“All operations have a place” does not mean all semantics move into shell-cli.
The mechanism moves; domain intent stays with its owner.
The end state should make direct process creation in Colleague exceptional and
mechanically guarded. Project-code execution must not bypass the selected
shell environment merely because it came from run_tests, lint, or a hook
instead of run_command.
6. Library first, CLI second
The importable API is primary. The CLI is a front end over exactly the same
operation engine.
Canonical CLI groups:
shell env describe|create|destroy
shell fs read|list|stat|write|edit|media
shell process exec|shell
shell git status|diff|worktree|commit|merge
shell policy check|explain
shell operation show
shell whoami|learn|explain|doctor
Compatibility aliases such as shell read, shell edit, and shell run may
exist, but they must not distort the library model.
Every command supports structured JSON. Results go to stdout; diagnostics go
to stderr. Long-running operations support streaming events and cancellation.
Mutation and execution verbs preview by default in the human/agent CLI and
require --apply. Reads execute immediately. Imported callers must also state apply=True explicitly. The Colleague compatibility adapter passes it for
today's immediately-applied write_file, edit_file, and run_command
semantics.
7. Layered safety model
Safety has four distinct layers. Do not merge their claims.
Capability authorization — Colleague. Roles decide which semantic tools
may be offered and invoked.
Operation policy — shell-cli. The normalized operation is allowed,
denied, or previewed under an operator-supplied policy snapshot.
Execution isolation — runner. Host mode is a guard; container mode is a
declared isolation boundary with a documented profile.
Outcome validation — Colleague. Tests, lint, integrity, acceptance, and
handoff gates decide whether the work is acceptable.
HostRunner is a guard, not a sandbox. Structured filesystem primitives
are path-confined; a raw host shell command can escape the repository through
shell expansion, interpreters, absolute paths, network calls, or child
processes. Documentation and result metadata must say this plainly.
Container baseline
The default project container profile should include:
non-root user mapped to appropriate host UID/GID
no privileged mode and no Docker socket
all capabilities dropped unless explicitly restored
network disabled by default
read-only container root filesystem
only the selected work root mounted writable
explicit dependency/cache volumes
bounded CPU, memory, pids, output, and wall time
explicit, redacted secret injection
Dependency preparation may be a separate network-enabled operation that
populates a cache/volume. It must not quietly enable network during the sealed
test or execution phase.
A linked Git worktree contains a .git pointer into the source repository's
common Git directory. Mounting only the worktree into a container therefore
does not preserve today's in-worktree Git behaviour. The container milestone
must explicitly choose between:
project containers do not receive Git metadata; structured Git operations run
through the trusted control plane; or
the environment receives isolated Git metadata that cannot mutate unrelated
host refs.
Do not solve this by broadly mounting the host repository's common .git
directory writable. That would give project code a path back into operator refs
and weaken the isolation claim.
Policy compatibility
The evaluator and policy data structures move to shell-cli. Location resolution
does not:
shell core accepts explicit policy data/files and has no .colleague import
the Colleague adapter preserves existing repo/user/model overlays and file
format during migration
shell-native policy can be versioned independently
absent policy and malformed configured policy are distinct states; native
policy should not silently turn a malformed declared gate into allow-all
8. Evidence is a product surface
Every operation produces a structured evidence record suitable for the model,
the operator, telemetry, and a validator such as Heimdall.
Minimum evidence:
operation id, caller, task and tool
requested and normalized operation
preview/applied state
policy verdict and matched rule
environment id, workspace kind, runner, root and cwd
mounts, network and resource profile
start/end/duration
exit code or structured error
separately captured stdout/stderr with bounded rendering
truncation markers plus hashes/byte counts of full captured output when known
known filesystem/Git effects and whether that effect list is complete
Secrets are never recorded. Evidence failure must not turn an executed action
into an unrecorded success; the result must honestly mark degraded evidence.
Colleague maps neutral results into its existing ToolOutcome, Step, media
message, progress, statistics, and artifact shapes. shell-cli must not import
Colleague contracts.
9. Pure-stdlib core
The base package has zero third-party runtime dependencies.
filesystem, policy, subprocess, JSON, hashes, dataclasses, and streaming use
the Python standard library
Git, Docker, and Podman are optional external executables discovered on PATH,
not Python SDK dependencies
optional protocol/rendering integrations live behind extras
a zero-dependency/import-leak guard is required from the first implementation PR
The dependency direction is one-way:
Colleague → shell-cli
shell-cli ↛ Colleague
10. Compatibility invariants
The first consumer migration is successful only if Colleague loses no behaviour.
The six existing OpenAI tool schemas remain byte-equivalent, including order
and descriptions, until an intentional separately-reviewed schema change.
Role curation and runtime refusal remain intact.
Hook rewrite precedes command policy.
Policy denial remains a non-success step with the same model-visible reason
and telemetry meaning.
write_file / edit_file still apply immediately through the adapter.
run_command remains a fresh shell, rooted cwd, bounded timeout, and current
output rendering during the parity milestone.
line numbering, truncation, media size/type limits, and error messages remain
compatible.
changed-file aggregation, subagent changes, and bytes_written ROI accounting
remain intact.
Build brief: shell-cli — the guarded local operations plane for AI agents
This issue is the architectural source of truth for
shell-cli. It supersedesthe original narrow “extract six tools from Colleague” framing while preserving
that extraction as the first compatibility slice.
The identity is settled:
shell-clishellshellagentculture/colleagueThe repository is currently a green scaffold. Development has not started, so
we will establish the complete boundary before copying implementation.
1. Vision
Colleague should decide why, when, and which action to take.
shell-cli should provide one place to plan, authorize, execute, observe, and
record the local operation.
That includes more than the six model-facing tools. Files, arbitrary commands,
curated tests, lint, hooks, Git/worktree mechanics, and trusted external CLIs
all eventually need the same operation lifecycle even when their higher-level
semantics stay elsewhere.
The separation is:
shell-cli is not another agent. It contains no model, planner, memory, web
browser, or domain workflow. It is the execution substrate beneath them.
2. The operation is the core abstraction
An operation is any local observation, mutation, process invocation, or
environment lifecycle action.
The boundary is work-affecting I/O, not every internal byte Colleague ever
writes. Runtime-private bookkeeping such as artifacts, trace/flight feeds,
telemetry buffers, caches, and lock files remains with its owning runtime unless
it executes code or touches the target workspace. This prevents shell-cli from
becoming a god-layer around ordinary application internals.
Every operation follows one lifecycle:
flowchart LR C["Colleague intent"] --> O["Operation"] O --> P["Policy + preview"] P --> B["Environment backend"] B --> E["Result + evidence"] E --> CThe pure library contract should be provider-neutral and JSON-serializable:
The concrete names may improve during design, but the semantics are fixed:
Operationobserve,mutate,execute, orlifecycleOperationResultpreviewed,denied,succeeded,failed, ortimed_outA preview is never reported as success. A shell command preview describes what
would run; it does not pretend to predict the command's effects.
3. Environments have two independent axes
Do not encode “host,” “worktree,” and “Docker” as one overloaded mode.
Workspace/root axis
Runner axis
HostRunnerContainerRunnerusing Docker or PodmanThe useful matrix is:
Colleague already uses worktree + host for
work/driveand parallelchildren. Interactive sessions run checkout + host, and failed worktree
creation may degrade to in-place execution. shell-cli must preserve those
behaviours during migration rather than rebuilding a simpler competing
worktree system.
An environment therefore distinguishes at least:
source_root: trusted repository/control contextwork_root: the tree operations may observe/changerunner: host/container implementationPolicy is snapshotted from trusted control context before model mutations; an
agent must not be able to edit its own active authorization by changing a file
inside the work root.
4. Three operation profiles
Every subprocess must declare why it is running. Avoid treating all
subprocess.runcalls as equally trusted.projectExecutes repository-controlled code:
Target: containerized by default, network disabled unless explicitly granted.
controlExecutes trusted agent/control-plane programs:
gitworktree/handoff mechanicsdevague,eidetic,culture, andcoherenceCLIsHost execution is expected, but it should use argv vectors, executable
allow-lists, minimal environment inheritance, explicit cwd, bounded output, and
evidence. Raw shell strings are not appropriate for control operations.
observeStructured reads such as file listing, text/media loading, status, and diff.
These are confined to the selected root and never imply process isolation.
5. Where every Colleague operation goes
“All operations have a place” does not mean all semantics move into shell-cli.
The mechanism moves; domain intent stays with its owner.
read_file,list_dirfs.read,fs.listwrite_file,edit_filefs.write,fs.editview_mediafs.mediaobservationrun_commandprocess.shell, profileprojectrun_testsprocess.exec, profileprojectprocess.exec, profileprojectprocess.execwith declared profilefinish,deepthink, model completionwebglass-cliproviderThe end state should make direct process creation in Colleague exceptional and
mechanically guarded. Project-code execution must not bypass the selected
shell environment merely because it came from
run_tests, lint, or a hookinstead of
run_command.6. Library first, CLI second
The importable API is primary. The CLI is a front end over exactly the same
operation engine.
Canonical CLI groups:
Compatibility aliases such as
shell read,shell edit, andshell runmayexist, but they must not distort the library model.
Every command supports structured JSON. Results go to stdout; diagnostics go
to stderr. Long-running operations support streaming events and cancellation.
Mutation and execution verbs preview by default in the human/agent CLI and
require
--apply. Reads execute immediately. Imported callers must also stateapply=Trueexplicitly. The Colleague compatibility adapter passes it fortoday's immediately-applied
write_file,edit_file, andrun_commandsemantics.
7. Layered safety model
Safety has four distinct layers. Do not merge their claims.
may be offered and invoked.
denied, or previewed under an operator-supplied policy snapshot.
declared isolation boundary with a documented profile.
handoff gates decide whether the work is acceptable.
For Colleague, the ordering must remain:
Host honesty
HostRunneris a guard, not a sandbox. Structured filesystem primitivesare path-confined; a raw host shell command can escape the repository through
shell expansion, interpreters, absolute paths, network calls, or child
processes. Documentation and result metadata must say this plainly.
Container baseline
The default
projectcontainer profile should include:Dependency preparation may be a separate network-enabled operation that
populates a cache/volume. It must not quietly enable network during the sealed
test or execution phase.
A linked Git worktree contains a
.gitpointer into the source repository'scommon Git directory. Mounting only the worktree into a container therefore
does not preserve today's in-worktree Git behaviour. The container milestone
must explicitly choose between:
through the trusted control plane; or
host refs.
Do not solve this by broadly mounting the host repository's common
.gitdirectory writable. That would give project code a path back into operator refs
and weaken the isolation claim.
Policy compatibility
The evaluator and policy data structures move to shell-cli. Location resolution
does not:
.colleagueimportformat during migration
policy should not silently turn a malformed declared gate into allow-all
8. Evidence is a product surface
Every operation produces a structured evidence record suitable for the model,
the operator, telemetry, and a validator such as Heimdall.
Minimum evidence:
Secrets are never recorded. Evidence failure must not turn an executed action
into an unrecorded success; the result must honestly mark degraded evidence.
Colleague maps neutral results into its existing
ToolOutcome,Step, mediamessage, progress, statistics, and artifact shapes. shell-cli must not import
Colleague contracts.
9. Pure-stdlib core
The base package has zero third-party runtime dependencies.
the Python standard library
not Python SDK dependencies
The dependency direction is one-way:
10. Compatibility invariants
The first consumer migration is successful only if Colleague loses no behaviour.
and descriptions, until an intentional separately-reviewed schema change.
and telemetry meaning.
write_file/edit_filestill apply immediately through the adapter.run_commandremains a fresh shell, rooted cwd, bounded timeout, and currentoutput rendering during the parity milestone.
compatible.
bytes_writtenROI accountingremain intact.
Characterization tests must compare the legacy and new execution paths against
the same fixtures before the legacy implementation is removed.
11. Target package shape
Illustrative, not a mandate on filenames:
Avoid a giant
Shellgod object. Operation handlers should be small andcomposable behind one lifecycle pipeline.
12. Delivery plan
This issue is the umbrella contract. Implement it in independently reviewable
vertical slices; do not ship one giant rewrite.
Milestone 0 — inventory and characterization
classify runtime-private bookkeeping as exempt or mediated
project,control,observe, or not a shell operationMilestone 1 — operation core + parity provider
Operation,OperationResult,Environment, policy, evidence,confined filesystem operations, and
HostRunnerMilestone 2 — Colleague delegates the six tools
Milestone 3 — route all Colleague local operations
run_tests, lint, affected tests, configured project hooksMilestone 4 — container runner
Milestone 5 — ecosystem providers
webglass-clias a separate semantic provider13. Test ownership
Tests move according to responsibility, not by filename.
shell-cli owns
Colleague retains
ToolOutcomeand media-message adaptation14. Definition of done
runtime-private bookkeeping is explicitly accounted for.
15. Non-goals
webglass-cliowns them)eidetic-cliowns them)16. Infographic corrections
The current first-draft infographic is visually useful, but the next version
should reflect this issue:
17. First implementation decision
Before large-scale work, reply with a concrete Milestone 0/1 plan that names:
Use Devague to challenge the plan for boundary leaks, false safety claims,
version skew, and operations that would bypass the selected environment.