RFC: Running uf in a FullSend BYOA container #437
Replies: 5 comments
|
I used an agent to post this. If it sounds authoritative and a command to do it this way that was not intentional. I only mean to share what I discovered. Investigation Complete — Approach A Confirmed, Execution Plan BelowAfter a deep investigation of both the FullSend codebase ( Key Findings1. FullSend's runtime is currently hard-locked to Claude Code.
2. OpenCode is explicitly on FullSend's roadmap.
3. uf already runs fully headless via The opencode run --model "${MODEL}" --format json --file review_prompt.txt \
-- "Review this PR according to the attached prompt."
4. The
type Runtime interface {
Name() string
System() string
ConfigDir() string
WorkspaceDir() string
EnvExports() []string
Bootstrap(input BootstrapInput) error
Run(ctx, RunParams, printer, start, metrics) (exitCode, error)
ClearIterationArtifacts(sandboxName string) error
}
5. Security hook gap (acceptable for read-only, must close for write-capable). Claude Code has Locked Decisions
Parity Modeluf's agents/commands/skills/packs live in the repo's committed
Increment Roadmap
Increment 1 —
|
| Risk | Mitigation |
|---|---|
| Security-hook gap (no OpenCode PreToolUse/PostToolUse) | Fine for read-only Inc1–2; must close before write-capable Inc4 — options: OpenCode plugin shim, wrapper-enforced tool allowlisting, or host-side diffing of sandbox writes. Needs its own spike. |
| Runtime is per-repo, not per-harness | Pilot repo runs all agents on OpenCode (fine for uf-native repo). Mixed-runtime repos need an upstream per-harness override. |
--format json token/cost fidelity unknown |
Metrics partial until #1935 lands; acceptable for Inc1. |
| Interactive commands never behave identically headless | By design — async Q&A replaces them. Set this expectation with PSDev. |
Answers to Original Open Questions
- Does FullSend support OpenCode as runtime? Not today — runtime is locked to Claude + dummy. But OpenCode is on the Phase 2 roadmap (#1260, #1935) with a planned
parseOpenCodeStream(). We will contribute the implementation upstream. - Custom image? Extend
fullsend-sandbox+npm install opencode-ai+dnf install uf. Dewey/Ollama deferred. - Headless adaptation?
opencode run --format jsonalready works headless (proven bycouncil-review-action). InteractiveAskUserQuestionreplaced by async GH-comment Q&A. - Credential delivery?
OPENCODE_CONFIG_CONTENTenv var (Vertex provider config) +GOOGLE_APPLICATION_CREDENTIALSviahost_files— mirrorscouncil-review-actionexactly. - Pilot repo? Yes,
unbound-force— per-repo install withruntime: opencode. - Per-org vs per-repo? Per-repo (custom harness routing requires it per ADR 0044/0061).
- Hybrid? No throwaway skill MVP. Straight to parity. Other teams adopt by pointing to the same
OpenCodeRuntimeupstream + their own.opencode/directories.
I used an agent to post this. If it sounds authoritative and a command to do it this way that was not intentional. I only mean to share what I discovered.
Revised execution plan — uf as a FullSend BYOA (opencode runtime)Update to the Aug-5 execution plan above. Re-verified against the current state of both repos, the merged opencode PRs, @beatrizmcouto's story breakdown (#508–#518), @sonupreetam's per-repo onboarding spike ( Confirmed direction
Already landed upstream
Stories
What changed since Aug 5
Implementation detailEach story body (#508–#518 + #519) now includes an appended "Implementation Notes" section with code sketches, harness YAML, Containerfile, host scripts, CLI signatures, schema drafts, operational references from the onboarding spike, and a troubleshooting playbook. The full working plan is maintained in Key risks
@sonupreetam @beatrizmcouto — feedback welcome. The plan is ready for Phase 0 (#509) and Onboarding (#519) to start in parallel. |
Review FeedbackIts a thorough RFC and execution plan and the direction is sound — Approach A (full parity), incremental rollout, and security-before-writes ordering are all correct calls. I've reviewed the Discussion alongside the 11 child stories (#509–#519) and the Divisor triage panel results. Three items need resolution at this level before the later increments can be scoped: 1. Terminology gap"FullSend", "BYOA", "harness", "validation_loop.script", "fullsend-opencode", and related terms have zero presence in the unbound-force codebase. The triage panel flagged this independently on every single child story. This isn't blocking for early stories (#509, #514), but it creates a friction multiplier across the entire backlog. Request: Add a glossary section to this Discussion or to the epic (#508) that maps each term to its definition and links to external documentation. This unblocks downstream spec work across all stories. 2. Phantom artifact referencesSeveral stories reference artifacts that do not exist:
Request: Either create these artifacts ahead of the stories that reference them, or update the stories to state these are net-new 3.
|
Response to review feedback@yvonnedevlinrh — thank you for the thorough review. All three items have been addressed, and the four observations are acknowledged with specific commitments below. 1. Terminology gap — resolvedA Glossary section has been added to the epic (#508) covering all FullSend/BYOA terms (FullSend, BYOA, harness, validation_loop.script, fullsend-opencode, runtime/OpenCodeRuntime, OpenShell, mint, inference/WIF, sandbox_hooks/Tirith, TranscriptHandler/ndjson, Divisor council, uf gate, forge). This is the canonical reference — each term links to the relevant external doc or child story. 2. Phantom artifact references — clarifiedTwo of the three references are not phantom — they are cross-repo references to artifacts in the fullsend repo (
The issue was labeling, not existence. All three stories have been updated:
3.
|
| Observation | Response | Updated |
|---|---|---|
#514 sequencing — unanimous VALID, uf doctor precedent |
Agreed. #508 now notes #514 may enter spec pipeline alongside #509. | #508 |
Shell injection in #510 — fmt.Sprintf("cd %s && …") flagged HIGH |
Valid concern. However, exec.Command with argv separation is not applicable here — the sandbox boundary is openshell sandbox exec -- sh -c <command> (sandbox.go:684), which requires a shell string. The correct fix is shell-escaping + input validation, mirroring the established pattern in claude.go:297,314,318,322,326 (single-quote wrapping + '\'' escape + charset allowlist). Security requirement added to #510. |
#510 |
/uf.answer injection in #513 — untrusted comment content |
Valid. Input sanitization requirements added: length cap, control-char stripping, data-not-instructions treatment, shape validation, audit trail. | #513 |
| Coverage strategies (Constitution IV) | Agreed — this is a spec-phase deliverable, not an issue-level AC. Noted in #508 process section: each story's spec/plan includes coverage strategy before implementation. | #508 |
|
Bringing up a critical blind spot we need to account for in this RFC: agent prompt and definition files across Once we drop these agents into a network-isolated FullSend BYOA container ( Since this was initially overlooked, we need a clean way to bridge local execution parity with strict container isolation without forcing a massive, painful rewrite of every agent prompt. Here are three architectural paths we could take to solve this: 1. The Intercepting
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Context
FullSend's built-in code agent implements whatever work is assigned to it — it does not enforce a spec-first workflow. For teams practicing spec-driven development (via Speckit and OpenSpec), this means the discipline that exists in local development environments disappears once work moves to FullSend.
uf already solves this problem: constitution enforcement, phase boundaries, Speckit/OpenSpec routing logic, and convention packs ensure that agents do not implement without an approved spec. The challenge is bringing that into a FullSend container with full parity — the agent must behave identically whether running locally in OpenCode or inside a FullSend sandbox.
Core question: How should uf run in a FullSend BYOA container? The standard BYOA path (skills, config overrides) was designed for lightweight customizations. uf is a full methodology with orchestration, 48 commands, convention packs, and review council — a different category of use case.
Non-negotiable requirement: Spec-driven development must be enforced. The agent must refuse to implement without an approved spec.
How FullSend BYOA Works
A custom agent in FullSend has two parts:
The key mechanism for customization is
base:composition — inherit a built-in agent and override or extend specific fields. Skills mount domain knowledge into the sandbox that the agent reads before acting.Reference: Bring Your Own Agent guide
Approach A: FullSend as Infrastructure, OpenCode + uf as Runtime (Recommended)
Treat FullSend as the infrastructure layer (sandbox, credentials, dispatch, GitHub event routing) and run OpenCode + uf as the agent runtime inside the container. The agent is OpenCode reading the repo's
.opencode/directory — same as local development.Why this approach:
.opencode/directory, same commands, same behavior locally and in FullSend. No "FullSend-lite" version to maintain..opencode/commands/and executes them directly. No translation to FullSend skills needed..opencode/uf/packs/automatically.What the BYOA harness provides:
The harness is thin — it handles plumbing. The methodology lives in the repo's
.opencode/directory, same as always.Tradeoffs:
.opencode/in the repo)Approach B: Full uf Binary in Default Sandbox
Install the uf binary in a custom sandbox image but use FullSend's native agent runtime (not OpenCode). The agent definition references uf as a tool it can call.
Tradeoffs:
ufcommands from agent promptApproach C: Portions (Skill-Based)
Extract the spec-driven workflow as a FullSend skill. The agent inherits from the built-in code agent and gains spec awareness via mounted knowledge:
Tradeoffs:
Component Mapping Across Approaches
Connection to complytime/roadmap#50
RFC: Integrating SpecDrivenDev tooling after AAC Review proposes using OpenSpec as the bridge between ADR approval and implementation. This custom agent is what makes that proposal concrete within FullSend:
.fullsend/config.yamlOpen Questions
Security & Production Readiness Findings
After investigation with the FullSend team (via #1260), the following blockers exist before OpenCode can be a production runtime in FullSend:
Security Blockers (FullSend must own — not fixable upstream)
OpenCode's SECURITY.md explicitly states its permission system is a "UX feature, not a security boundary." In headless mode, all permissions are granted by default. The OpenCode project only fixes browser-exploitable RCEs — systemic hardening is out of scope per their threat model.
FullSend must implement compensating controls:
Dependency Chain (Priority Order)
No published timeline exists for the OpenCode alignment workstream.
Revised Approach
Given these findings, full parity (Approach A) is a medium-term target, not an immediate deliverable. The interim path:
Next Steps
.opencode/ecosystem in FullSend sandboxAll reactions