Harness ring — agent runtime config
Harness ring — agent runtime config
Section titled “Harness ring — agent runtime config”What it does: Writes the settings-file-style config that the agent's runtime obeys (PreToolUse hooks, allow/deny lists).
1. Vision context
Section titled “1. Vision context”Some agent runtimes natively support a settings file that constrains what the agent can do — Claude Code's settings.json is the canonical example. Operators editing that file at deploy time is brittle; under TapPass's "live policy" model, the file must be derived from policy and updated on sync.
This layer is the bridge: it knows how to write a runtime-appropriate config blob into the agent's filesystem from the keyring's layer-2 slice. For runtimes that don't have a native settings file (a custom LangChain agent, say), this layer writes a tappass-agent-recognized config that the SDK reads.
The harness layer is the highest leverage layer when it works (the runtime self-enforces) and cheap to bypass if you can edit it (the kernel layer is the backstop). See concepts/governed-agents-architecture.md §9.2 for the bypass matrix.
2. Functional specification
Section titled “2. Functional specification”Inputs: the layer-2 slice of a SandboxConfig, plus the agent runtime identifier (provided by tappass-host start --agent <package>):
layer_2_harness: runtime: claude-code # or "langchain-react", "tappass-agent-default", … permissions: allow: - "Read(/var/run/tappass/sandboxes/*/agent-data/**)" - "Bash(git *)" deny: - "Bash(rm -rf *)" hooks: PreToolUse: - command: "tappass-agent verify-toolcall" blocking: trueOutputs: a written file in the agent's sandbox FS (e.g. /var/run/tappass/<sandbox_id>/agent-config/settings.json) and an inotify-equivalent signal so the running agent can reload.
Error cases:
- Unknown runtime identifier → emit
harness_layer_unsupported_runtime: <id>, write a generictappass-agentconfig as a fallback, continue. - Atomic rename fails → retry once, then fail sandbox apply.
Non-goals:
- Enforcing the rules ourselves (the runtime does that).
- Choosing what to allow/deny (the policy-to-sandbox-config-builder).
3. Technical design
Section titled “3. Technical design”Where it lives: tappass-host/src/layers/harness.py with a per-runtime adapter pattern. Adapters: claude_code.py, langchain_react.py, tappass_agent_default.py, …
Adapter contract:
class HarnessAdapter: runtime_id: str def materialize(self, layer_2_config: dict) -> bytes: """Render the runtime-specific config bytes.""" def target_path(self, sandbox_id: str) -> Path: """Where in the sandbox FS this config lives.""" def reload_signal(self, sandbox_id: str) -> None: """How to tell the running agent to reload (inotify, signal, restart)."""At sandbox start: materialize the config; atomic-write to the target path; (no signal — the agent reads on first start).
On sync push: materialize new config; atomic-rename; signal the agent.
4. Definition of done
Section titled “4. Definition of done”- All
acceptance_criteriapass. - Adapter for at least one canonical runtime (Claude Code) implemented and tested.
- Generic fallback adapter for unrecognized runtimes implemented.
- Integration test: settings file written; agent runtime observes the file and respects the rules.
- Sync push test: settings file updated atomically; running agent reloads without restart.
- Documentation in spec.
5. Coordination notes
Section titled “5. Coordination notes”With host-runtime-cli: invoked second in the layer apply sequence (after kernel, before codemode/MCP/gateway).
With agent-client-sdk: the SDK reads the settings file and exposes the rules to agent code (so a LangChain ReAct agent that wraps tappass-agent automatically respects them).
Open questions:
- (Q) Which agent runtimes should we ship adapters for in v1? Lean: Claude Code, LangChain ReAct (via tappass-agent), and one OSS agent framework (CrewAI or LlamaIndex). Owner: this component.
- (Q) What if the agent runtime doesn't support live reload? Lean: the host runtime CLI restarts the sandbox on layer-2 changes if
reload_signalisn't supported by the adapter. Owner: host-runtime-cli.
6. Out of scope
Section titled “6. Out of scope”- Adapters for every conceivable agent runtime — ship adapters as customer demand surfaces.
- Enforcing rules at runtime if the runtime ignores its own settings file (the kernel layer is the backstop).