Agent Protocol
Last verified against code: 2026-03-17
Summary
Gas City’s agent runtime boundary lives ininternal/runtime/.
runtime.Provider is the low-level contract for starting, stopping,
attaching to, nudging, and observing agent sessions. The surrounding pieces
that make that usable at the product level are:
internal/agent/for session naming and startup hintscmd/gc/template_resolve.gofor building runtime start configsinternal/session/for session bead records, waits, and blocked-turn state
- runtime manages live sessions and I/O
- agent helpers define naming and startup-hint data
- session helpers manage higher-level session bookkeeping
Key Concepts
runtime.Provider: The core runtime interface ininternal/runtime/runtime.go. It owns session lifecycle, communication, metadata, and observation.runtime.Config: Start-time configuration for a session. Includes command, env, working directory, startup hooks, overlays, and copy rules.agent.StartupHints: The resolved config-side hints that are converted intoruntime.Config.agent.SessionNameFor(): The single source of truth for runtime session naming, defined ininternal/agent/session_name.go.- Beacon: A startup identification string generated by
internal/runtime/beacon.goso restarted sessions are easy to recognize in tools like/resume. - Config fingerprint: A deterministic hash from
internal/runtime/fingerprint.goused to detect runtime drift. - Dialog dismissal: Shared startup-dialog handling in
internal/runtime/dialog.go. - Waits and pending interactions: Higher-level blocked-session and wait
behavior managed in
internal/session/.
Architecture
Start Flow
- Config and provider defaults are resolved in
cmd/gc/. template_resolve.gobuilds the final command, env, overlays, staged files, and startup hints.runtime.Provider.Start()receives aruntime.Config.- Provider-specific startup runs:
- tmux creates or attaches to a tmux session
- subprocess launches a child process
- exec delegates to a script
- k8s creates or resumes a pod-backed session
- Shared helpers handle session fingerprinting, beacons, and startup-dialog dismissal where the provider supports it.
Runtime Operations
runtime.Provider exposes the main operations used throughout the CLI and
controller:
- lifecycle:
Start,Stop,Interrupt - observation:
IsRunning,IsAttached,ProcessAlive,Peek,ListRunning,GetLastActivity - interaction:
Attach,Nudge,SendKeys - metadata:
SetMeta,GetMeta,RemoveMeta - staging and reapply:
CopyTo,RunLive
runtime/runtime.go:
InteractionProviderIdleWaitProviderImmediateNudgeProvider
Providers
- tmux: Primary interactive runtime in
internal/runtime/tmux/ - subprocess: Local non-interactive runtime in
internal/runtime/subprocess/ - exec: Script-backed runtime in
internal/runtime/exec/ - k8s: Kubernetes runtime in
internal/runtime/k8s/ - acp, auto, hybrid: Routing/adaptation layers in
internal/runtime/
Invariants
- Session names come from
agent.SessionNameFor()and must be stable for a given city/agent/template combination. - Runtime drift detection uses
runtime.ConfigFingerprint()rather than ad-hoc field comparisons. - Providers must treat
Stopas idempotent. ProcessAlivewith an empty process list returns true by contract.- Metadata is runtime-owned state keyed by session name.
- Higher-level wait and pending-interaction behavior must layer on top of the runtime contract instead of bypassing it.
Interactions
| Depends on | How |
|---|---|
internal/agent | Session naming and startup-hint structures |
internal/config | Provider presets and resolved agent settings |
internal/session | Session bead state, wait lifecycle, and blocked-turn helpers |
| Depended on by | How |
|---|---|
cmd/gc/cmd_start.go | Starts runtimes for configured agents |
cmd/gc/reconcile.go | Uses runtime liveness and drift signals |
cmd/gc/cmd_session.go | Attach, list, inspect, and session-level commands |
cmd/gc/cmd_nudge.go | Idle-aware and queued nudge delivery |
internal/api/ | Session-aware API surfaces and status views |
Code Map
| Path | Responsibility |
|---|---|
internal/runtime/runtime.go | Provider, Config, optional runtime extensions |
internal/runtime/fingerprint.go | Deterministic runtime config hashing |
internal/runtime/beacon.go | Startup beacon formatting |
internal/runtime/dialog.go | Shared startup-dialog handling |
internal/runtime/fake.go | In-memory fake runtime for tests |
internal/runtime/tmux/ | Interactive tmux-backed runtime |
internal/runtime/subprocess/ | Non-interactive subprocess runtime |
internal/runtime/exec/ | Script-backed runtime provider |
internal/runtime/k8s/ | Kubernetes-backed runtime provider |
internal/runtime/acp/ | ACP-backed runtime provider |
internal/runtime/auto/ | Automatic routing between runtime backends |
internal/runtime/hybrid/ | Hybrid routing between local and remote backends |
internal/agent/hints.go | StartupHints |
internal/agent/session_name.go | Session naming |
cmd/gc/template_resolve.go | Builds runtime configs from resolved agent config |
internal/session/manager.go | Higher-level session manager for session beads |
internal/session/waits.go | Wait state helpers |
Testing
internal/runtime/runtimetest/conformance.goprovides runtime conformance coverageinternal/runtime/fake_test.goandinternal/runtime/fake_conformance_test.govalidate the fake runtimeinternal/runtime/tmux/contains tmux unit and startup testsinternal/runtime/k8s/provider_test.gocovers the Kubernetes providerinternal/session/manager_test.goandinternal/session/manager_states_test.gocover higher-level session bookkeeping layered on top of the runtime
Known Limitations
- Provider capabilities differ: interactive attach, idle waiting, and pending interactions are not uniformly supported everywhere.
- Metadata persistence depends on the backing provider.
- Session bookkeeping and runtime execution are deliberately separate, which
means some contributor workflows need to inspect both
internal/runtime/andinternal/session/.
See Also
- Health Patrol for liveness and drift handling
- Prompt Templates for what gets delivered into sessions once they start