Skip to content

refactor(runtime): register opencode as a stub runtime - #6035

Merged
waynesun09 merged 4 commits into
fullsend-ai:mainfrom
sonupreetam:feat/opencode-runtime
Aug 12, 2026
Merged

refactor(runtime): register opencode as a stub runtime#6035
waynesun09 merged 4 commits into
fullsend-ai:mainfrom
sonupreetam:feat/opencode-runtime

Conversation

@sonupreetam

@sonupreetam sonupreetam commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Register "opencode" as an agent runtime backend via runtime.Resolve() with a stub OpenCodeRuntime that satisfies both Runtime and TranscriptHandler interfaces. The stub is not added to config.ValidRuntimes() — it is resolvable internally for dev/testing but not user-selectable via fullsend github --runtime or fullsend admin install --runtime until the runtime is functional.

Note: This stub does not resolve #1935. The format-neutral TranscriptHandler contract (#1935) remains a hard prerequisite before Run() and TranscriptHandler methods can be implemented for real. Extract methods return explicit not-implemented errors referencing #1935 to prevent silent success claims.

Related Issue

Refs #1260
Refs #1935

Changes

  • Add case "opencode" to runtime.Resolve() returning a Backend with OpenCodeRuntime
  • Create internal/runtime/opencode.go — stub struct with:
  • Add compile-time interface assertions for both Runtime and TranscriptHandler
  • Add opencode column to docs/runtimes.md security feature matrix (all N/A — stub; does not implement ClaudeHooksBootstrap)
  • Add opencode row to docs/runtimes.md registered runtimes table (noted as not in ValidRuntimes() until implemented)
  • Not added to config.ValidRuntimes() — avoids exposing a non-functional runtime on user setup paths and avoids updating ~5 doc/CLI surfaces that enumerate valid runtimes

Testing

  • make lint passes (stage changes first, then run)
  • Tests added/updated for new or modified logic

Checklist

  • PR title follows Conventional Commits (correct type, ! for breaking changes)
  • Commits are signed off (DCO) — human and human-directed agent sessions only
  • I wrote this contribution myself and can explain all changes in it

@sonupreetam
sonupreetam requested a review from a team as a code owner August 10, 2026 11:18
@github-actions

Copy link
Copy Markdown

E2E tests did not run

E2E tests run automatically for org/repo members and collaborators on pull requests.

For other contributors, a maintainer must add the ok-to-test label after the latest push.

See E2E testing guide for details.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

runtime: register opencode as a stub runtime backend

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Register opencode as a valid runtime in config validation and runtime resolution.
• Add a stub OpenCodeRuntime implementing Runtime + TranscriptHandler (not implemented).
• Document the new runtime and add tests covering registration and stub behavior.
Diagram

graph TD
  A["Runner (fullsend run)"] --> C["runtime.Resolve()"] --> D["Backend"] --> E["OpenCodeRuntime (stub)"] --> F[("Sandbox workspace")]
  C -->|"valid options / error msg"| B["config.ValidRuntimes()"]
  G["docs/runtimes.md"] -.->|"documents"| C

  subgraph Legend
    direction LR
    _mod["Module"] ~~~ _fs[("Sandbox storage")] ~~~ _doc[/"Documentation"/]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Defer registration until functional
  • ➕ Prevents users from selecting a runtime that cannot run yet
  • ➕ Avoids needing to support/maintain stub semantics and docs disclaimers
  • ➖ Slows incremental integration (cannot land selection plumbing early)
  • ➖ Harder to build integration in small, reviewable steps
2. Gate behind an explicit experimental flag (config/build)
  • ➕ Makes the non-functional status explicit at the configuration boundary
  • ➕ Allows early adopters without advertising it broadly
  • ➖ Adds extra branching/flag plumbing to config, docs, and tests
  • ➖ Still needs a clear error path for accidental usage

Recommendation: The current stub-registration approach is reasonable as an incremental first step, since it wires the runtime through the same validation and resolution paths as existing backends and returns a clear not-implemented error from Run(). Keep the runtime clearly marked as stub in docs (already done) and ensure any user-facing command path that triggers Run() surfaces the error cleanly.

Files changed (7) +124 / -1

Enhancement (2) +65 / -0
opencode.goIntroduce stub 'OpenCodeRuntime' implementing runtime + transcripts +62/-0

Introduce stub 'OpenCodeRuntime' implementing runtime + transcripts

• Adds a new 'OpenCodeRuntime' type that satisfies both 'Runtime' and 'TranscriptHandler'. Most methods are no-ops; 'Run()' returns exit code -1 with a not-implemented error, and compile-time interface assertions enforce contract compliance.

internal/runtime/opencode.go

registry.goResolve 'opencode' to 'OpenCodeRuntime' backend +3/-0

Resolve 'opencode' to 'OpenCodeRuntime' backend

• Adds an 'opencode' case to 'runtime.Resolve()' returning a Backend that uses 'OpenCodeRuntime' for both execution and transcript handling.

internal/runtime/registry.go

Tests (3) +57 / -0
config_test.goTest 'opencode' is included in valid runtimes +1/-0

Test 'opencode' is included in valid runtimes

• Updates 'TestValidRuntimes' to assert that 'opencode' is returned by 'ValidRuntimes()'. Prevents regressions where the runtime is added in one place but not another.

internal/config/config_test.go

opencode_test.goAdd unit tests for OpenCodeRuntime stub behavior +51/-0

Add unit tests for OpenCodeRuntime stub behavior

• Verifies runtime metadata (Name/System/dirs) and that 'Run()' fails with a not-implemented error and exit code -1. Also covers the no-op transcript/cleanup methods and ensures they are safe to call.

internal/runtime/opencode_test.go

registry_test.goTest resolving the 'opencode' backend +5/-0

Test resolving the 'opencode' backend

• Extends 'TestResolve' to ensure 'Resolve("opencode")' succeeds, returns the correct runtime name, and provides a non-nil transcript handler.

internal/runtime/registry_test.go

Documentation (1) +1 / -0
runtimes.mdDocument 'opencode' as a registered (stub) runtime +1/-0

Document 'opencode' as a registered (stub) runtime

• Adds 'opencode' to the registered runtimes table and marks it as a non-functional stub. This sets expectations while the backend is incrementally implemented.

docs/runtimes.md

Other (1) +1 / -1
config.goAllow 'opencode' in 'ValidRuntimes()' +1/-1

Allow 'opencode' in 'ValidRuntimes()'

• Extends the list of recognized runtime names to include 'opencode', enabling config validation and consistent error messaging.

internal/config/config.go

@qodo-code-review

qodo-code-review Bot commented Aug 10, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (1)

Grey Divider


Action required

1. Stub runtime selectable ✗ Dismissed 🐞 Bug ≡ Correctness
Description
Adding "opencode" to config.ValidRuntimes makes org/repo config and `fullsend admin install
--runtime` accept it even though OpenCodeRuntime.Run always returns a not-implemented error. Any run
configured for opencode will abort during agent execution.
Code

internal/config/config.go[177]

+	return []string{"claude", "dummy", "opencode"}
Relevance

●● Moderate

Could be intentional to register stub runtime early, but making it selectable can cause user-facing
hard failures.

PR-#5428
PR-#2407

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The repo uses ValidRuntimes() to validate user-selected runtimes in admin install and config
validation; after this PR it includes opencode. But the newly added OpenCodeRuntime.Run always
returns a not-implemented error, and the run loop aborts on any non-nil Run error, so any config
selecting opencode will hard-fail runs.

internal/config/config.go[175-178]
internal/cli/admin.go[375-384]
internal/config/config.go[334-338]
internal/runtime/registry.go[10-25]
internal/runtime/opencode.go[35-37]
internal/cli/run.go[1492-1503]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`opencode` is currently a stub runtime whose `Run` always returns a not-implemented error, but this PR adds it to `config.ValidRuntimes()`. That list is used by config validation and `fullsend admin install --runtime`, so users can generate/validate configs that will *always* fail at runtime.

### Issue Context
- `fullsend admin install` validates the selected runtime using `config.ValidRuntimes()`.
- Org/per-repo config validation also uses `ValidRuntimes()`.
- When selected, `OpenCodeRuntime.Run` returns a non-nil error, and the CLI run loop treats any non-nil error as a hard failure.

### Fix Focus Areas
- internal/config/config.go[175-178]
- internal/config/config_test.go[383-388]
- internal/runtime/opencode.go[35-37]

### What to change
Choose one approach and implement consistently:
1) **Do not expose stub runtimes via `ValidRuntimes()`** until functional.
  - Remove `opencode` from `ValidRuntimes()` and update tests/docs accordingly.
  - Keep `runtime.Resolve("opencode")` only if needed for internal dev/testing, or remove it too.

2) **Gate experimental runtimes**.
  - Introduce a separate allowlist for config/CLI selection (e.g., `ValidConfigRuntimes()`), or make `ValidRuntimes()` conditional on an explicit env/flag (e.g., `FULLSEND_EXPERIMENTAL_RUNTIMES=1`).
  - Update config validation and `admin install` to use the non-experimental list by default.

3) **Explicitly reject `opencode` in config validation** with a clear error until implemented.
  - This keeps the identifier reserved while preventing broken configs from being considered valid.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Late failure in bootstrap ✓ Resolved 🐞 Bug ➹ Performance
Description
OpenCodeRuntime.Bootstrap returns nil, so a run configured with opencode proceeds through sandbox
bootstrap and repo upload before failing in Run. Returning the not-implemented error from Bootstrap
would fail fast and avoid unnecessary setup work.
Code

internal/runtime/opencode.go[R33-36]

+func (OpenCodeRuntime) Bootstrap(_ BootstrapInput) error { return nil }
+
+func (OpenCodeRuntime) Run(_ context.Context, _ RunParams, _ *ui.Printer, _ time.Time, _ *RunMetrics) (int, error) {
+	return -1, fmt.Errorf("opencode runtime is not yet implemented")
Relevance

●●● Strong

Team has accepted fail-fast bootstrap validations before; returning not-implemented from Bootstrap
avoids wasted setup.

PR-#1780

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The run loop executes rt.Bootstrap before uploading the repo into the sandbox, but
OpenCodeRuntime currently returns nil from Bootstrap and only errors in Run, so a configured
opencode run will do extra setup work before inevitably failing.

internal/runtime/opencode.go[33-37]
internal/cli/run.go[1171-1221]
internal/cli/run.go[1458-1504]
internal/runtime/opencode_test.go[35-44]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`OpenCodeRuntime` is a stub and always fails in `Run`, but its `Bootstrap` currently returns `nil`. This delays the failure until after sandbox bootstrapping and repo upload work has already happened.

### Issue Context
The CLI run flow calls `rt.Bootstrap(...)`, then uploads the project into the sandbox, and only later calls `rt.Run(...)`. If the runtime is not implemented, failing during `Bootstrap` provides quicker feedback and avoids unnecessary sandbox work.

### Fix Focus Areas
- internal/runtime/opencode.go[33-37]
- internal/runtime/opencode_test.go[35-44]
- internal/cli/run.go[1171-1221]

### What to change
- Change `OpenCodeRuntime.Bootstrap(...)` to return the same not-implemented error as `Run` (or a more specific one like `fmt.Errorf("opencode runtime bootstrap is not yet implemented")`).
- Keep `Run` returning not-implemented as a safety net.
- Update `TestOpenCodeRuntimeNoopMethods` to expect an error from `Bootstrap` (and consider renaming the test since `Bootstrap` would no longer be a no-op).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. opencode lacks Planned callout 📜 Skill insight ≡ Correctness
Description
docs/runtimes.md documents the opencode runtime as a stub/not-yet-functional but does not use
the required > **Planned:** callout format with an issue link. This can mislead readers about
feature availability and violates the documentation standard for planned features.
Code

docs/runtimes.md[12]

+| `opencode` | OpenCode agent runs (stub — not yet functional) | Required |
Relevance

● Weak

Prior review rejected enforcing Planned callout + issue-link requirement for not-yet-implemented
docs.

PR-#3903

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1062082 requires any mention of not-yet-implemented features to use the `>
**Planned:** blockquote callout format and include an issue link. The added opencode` row
explicitly states it is a stub/not functional but does not use the required callout format and
provides no issue link.

docs/runtimes.md[12-12]
Skill: writing-user-docs

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The docs mention a not-yet-implemented/stub feature (`opencode` runtime) without using the required `> **Planned:**` callout format and without an issue link.

## Issue Context
`docs/runtimes.md` currently labels `opencode` as "stub — not yet functional" in the registered runtimes table. Per the documentation standard, any planned/not-yet-implemented feature must be documented using a `> **Planned:**` blockquote callout and must include a link to the relevant tracking issue (e.g., one of the issues referenced in the PR description).

## Fix Focus Areas
- docs/runtimes.md[12-12]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Compliance rules (platform): 54 rules

Grey Divider

Tip of the day
💡 Did you know, you can enable the Remediation agent and Qodo fixes findings in a dedicated fix PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread internal/config/config.go Outdated
Comment thread internal/runtime/opencode.go Outdated

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review-only findings (see inline comments). No approval/change-request action taken.

Comment thread internal/runtime/registry.go
Comment thread internal/runtime/opencode.go Outdated
Comment thread docs/runtimes.md Outdated
@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonupreetam
sonupreetam force-pushed the feat/opencode-runtime branch from 3e45cab to a768a59 Compare August 10, 2026 16:34
@sonupreetam
sonupreetam requested a review from waynesun09 August 10, 2026 17:33

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review-only findings (see inline comments, plus a reply on the existing ValidRuntimes thread rather than a duplicate comment). No approval/change-request action taken.

Findings without a diff anchor:

  • LOW — PR body claim "fail-fast at bootstrap, before sandbox setup" doesn't match the code path. Verified empirically on a768a59: sandbox creation (internal/cli/run.go:1022) precedes rt.Bootstrap (run.go:1245), which is the last step of the "Bootstrapping sandbox" phase, after scanRuntimeContent/bootstrapCommon/bootstrapEnv. The failure is fail-fast relative to Run() only. Suggest correcting the description to "fails during sandbox bootstrap, before agent execution".
  • LOW — Runtime.System() interface godoc drift. internal/runtime/runtime.go:48-51 still defines the return as "the model vendor … e.g. "anthropic""; with this PR two of three implementations return runtime identifiers (fullsend.dummy, opencode). Worth amending the godoc ("the model vendor where the runtime is vendor-specific, or the runtime identifier for multi-provider runtimes") here or in the follow-up.
  • LOW — validation behavior unpinned by tests. TestOrgConfigValidateRuntime (internal/config/config_test.go:389) never exercises opencode, so the "registered but unusable validates" behavior — whichever way the ValidRuntimes() decision lands — has no explicit test to catch a silent revert.

Overall: solid scaffolding PR — registration, interface conformance, fail-fast gate, and an honest security-matrix row. The substantive open question is selectability-before-implementability (see the ValidRuntimes thread); the ConfigDir() provisional marker is the one other change worth making before merge so follow-ups don't inherit an unverified path as settled.

Comment thread internal/runtime/opencode.go
Comment thread internal/runtime/opencode.go Outdated
Comment thread docs/runtimes.md Outdated
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown

Site preview

Preview: https://5be208d2-site.fullsend-ai.workers.dev

Commit: 202e0a804f8f2634a6a6ff05cea07d0c51a3c145

Register "opencode" in ValidRuntimes() and Resolve() with a stub
OpenCodeRuntime that satisfies both Runtime and TranscriptHandler
interfaces. All methods are no-ops or return not-implemented errors.

This is the first step toward OpenCode support tracked by fullsend-ai#1260.
Subsequent PRs will add stream parsing, bootstrap, run execution,
and transcript extraction.

Closes: n/a
Refs: fullsend-ai#1260, fullsend-ai#1935
Signed-off-by: sonupreetam <spreetam@redhat.com>
- Fail fast in Bootstrap() instead of only in Run(), avoiding
  unnecessary sandbox setup work before the not-implemented error
- Soften System() comment: remove unverified InitEvent reference,
  note event schema is TBD pending fullsend-ai#1935
- Fill in security feature matrix in docs/runtimes.md with OpenCode
  column (all N/A — stub; does not implement ClaudeHooksBootstrap)
- Add dedicated TestOpenCodeRuntimeBootstrap_NotImplemented test
- Remove Bootstrap from TestOpenCodeRuntimeNoopMethods (no longer
  a no-op)

Signed-off-by: sonupreetam <spreetam@redhat.com>
- Remove opencode from ValidRuntimes() — keep only in Resolve()
  so users cannot select it via fullsend github/admin install
  until the runtime is functional. Re-add when Run() is implemented.
- Mark ConfigDir() as provisional with comment noting the
  agent-writable workspace security concern (fullsend-ai#1260).
- Change ExtractTranscripts/ExtractDebugLog from no-op (nil) to
  not-implemented errors referencing fullsend-ai#1935, preventing silent
  success claims in CI logs.
- Update runtimes.md table to clarify opencode is resolved by
  Resolve() but not in ValidRuntimes() until implemented.
- Add TestOpenCodeRuntimeExtractStubs_NotImplemented test.

Signed-off-by: sonupreetam <spreetam@redhat.com>
- Test that config validation rejects 'opencode' in both org and
  per-repo configs (not in ValidRuntimes until implemented)
- Test ResolveFromPerRepoConfig with opencode (hand-written config
  bypassing validation can reach the stub)
- Verify Transcripts type assertion in TestResolve (ensures
  Resolve() returns OpenCodeRuntime for both Runtime and Transcripts)

Signed-off-by: sonupreetam <spreetam@redhat.com>
@sonupreetam
sonupreetam force-pushed the feat/opencode-runtime branch from f21eb27 to 202e0a8 Compare August 11, 2026 10:10
@sonupreetam
sonupreetam requested a review from waynesun09 August 11, 2026 16:05

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All review threads from both rounds are addressed and verified against the code at 202e0a8: opencode removed from ValidRuntimes() (locked in by config validation tests) while staying resolvable via Resolve(), Bootstrap()/extract stubs fail fast with explicit not-implemented errors referencing #1935, docs matrix and provisional ConfigDir() marker in place. Built the branch and ran internal/runtime + internal/config suites locally — all PR-related tests pass.

@waynesun09
waynesun09 added this pull request to the merge queue Aug 11, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 11, 2026
@sonupreetam

Copy link
Copy Markdown
Contributor Author

@waynesun09 Thank you for the reviews. The merge queue ejection was a transient GitHub API timeout during e2e scaffold setup,context deadline exceeded on POST /repos/.../git/blobs calls. Not related to the PR changes. It needs to be re-enqueued.

@waynesun09
waynesun09 added this pull request to the merge queue Aug 12, 2026
Merged via the queue into fullsend-ai:main with commit 13721ef Aug 12, 2026
16 checks passed
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 12, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 3:08 PM UTC · Completed 3:23 PM UTC

Commit: 202e0a8 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #6035 — register opencode as a stub runtime

Workflow shape: Human-authored PR by an external contributor (sonupreetam, read permission). No fullsend review, code, or fix agents ran — dispatch was correctly skipped by the permission gate. The only agent run was this retro (dispatched post-merge). Human review by waynesun09 was thorough: two rounds of inline feedback covering registry sequencing, fail-fast behavior, security matrix gaps, extract-stub silent success, and ValidRuntimes exposure. All findings were addressed before approval.

Actionable finding: Issue #1935 prematurely closed

Issue #1935 ("TranscriptHandler assumes file-based JSONL traces — needs format-neutral contract before second runtime") was manually closed by waynesun09 at 2026-08-12T15:05:35Z, simultaneous with the PR merge. However:

#1935 tracks a hard prerequisite — the format-neutral TranscriptHandler contract needed before the opencode runtime can be fully implemented. It should likely be reopened.

Existing issues corroborated by this PR

Review quality assessment

No agent review ran, so no agent-vs-human comparison is possible. The third-party qodo-code-review[bot] provided 3 automated findings (HIGH: stub selectable, MEDIUM: late bootstrap failure, LOW: missing docs callout). Two of these overlapped with the human reviewer's findings. The human reviewer additionally caught architectural issues (registry sequencing with #1935, ConfigDir provisional path concerns, extract-method silent success) that required deep project context — suggesting this class of change (new runtime integration) benefits from reviewer familiarity with the runtime integration strategy.

Proposals filed

@sonupreetam
sonupreetam deleted the feat/opencode-runtime branch August 12, 2026 17:27
waynesun09 pushed a commit that referenced this pull request Aug 22, 2026
Add PiRuntime as a stub implementation of the Runtime and
TranscriptHandler interfaces for the pi agent runtime
(earendil-works/pi), following the same pattern as
OpenCodeRuntime. The runtime is resolvable via
runtime.Resolve("pi") but intentionally excluded from
ValidRuntimes() until Bootstrap/Run are functional (per
the #6035 precedent).

Key additions:
- PiRuntime stub (pi.go): implements Runtime and
  TranscriptHandler with not-implemented errors, mirroring
  OpenCodeRuntime.
- parsePiStream (pi_progress.go): maps pi's --mode json
  NDJSON event stream to AgentEvent values. Handles session
  header (InitEvent), text, thinking, tool_result,
  message_end (TokensEvent), agent_end (ResultEvent), and
  error events. Detects stop_reason=error/aborted for the
  exit-0-override since --mode json exits 0 on model error.
  Falls back to synthesized ResultEvent on truncated streams.
- Test fixtures (testdata/pi/): recorded from pi 0.84.2
  --mode json output covering basic run, error run,
  reasoning, multi-step, malformed input, empty input, and
  truncated stream scenarios.
- Registry wiring: "pi" case in Resolve() switch.
- Documentation: pi column in docs/runtimes.md security
  feature matrix, config key support table, registered
  runtimes row, and pi-specific known constraints section.

Note: pre-commit could not run (sandbox network policy
blocked git fetch during hook environment init).
golangci-lint not available in sandbox. go vet passes.

Related to #6464
waynesun09 pushed a commit that referenced this pull request Aug 22, 2026
Add PiRuntime as a stub implementation of the Runtime and
TranscriptHandler interfaces for the pi agent runtime
(earendil-works/pi), following the same pattern as
OpenCodeRuntime. The runtime is resolvable via
runtime.Resolve("pi") but intentionally excluded from
ValidRuntimes() until Bootstrap/Run are functional (per
the #6035 precedent).

Key additions:
- PiRuntime stub (pi.go): implements Runtime and
  TranscriptHandler with not-implemented errors, mirroring
  OpenCodeRuntime.
- parsePiStream (pi_progress.go): maps pi's --mode json
  NDJSON event stream to AgentEvent values. Handles session
  header (InitEvent), text, thinking, tool_result,
  message_end (TokensEvent), agent_end (ResultEvent), and
  error events. Detects stop_reason=error/aborted for the
  exit-0-override since --mode json exits 0 on model error.
  Falls back to synthesized ResultEvent on truncated streams.
- Test fixtures (testdata/pi/): recorded from pi 0.84.2
  --mode json output covering basic run, error run,
  reasoning, multi-step, malformed input, empty input, and
  truncated stream scenarios.
- Registry wiring: "pi" case in Resolve() switch.
- Documentation: pi column in docs/runtimes.md security
  feature matrix, config key support table, registered
  runtimes row, and pi-specific known constraints section.

Note: pre-commit could not run (sandbox network policy
blocked git fetch during hook environment init).
golangci-lint not available in sandbox. go vet passes.

Related to #6464
waynesun09 pushed a commit that referenced this pull request Aug 22, 2026
Add PiRuntime as a stub implementation of the Runtime and
TranscriptHandler interfaces for the pi agent runtime
(earendil-works/pi), following the same pattern as
OpenCodeRuntime. The runtime is resolvable via
runtime.Resolve("pi") but intentionally excluded from
ValidRuntimes() until Bootstrap/Run are functional (per
the #6035 precedent).

Key additions:
- PiRuntime stub (pi.go): implements Runtime and
  TranscriptHandler with not-implemented errors, mirroring
  OpenCodeRuntime.
- parsePiStream (pi_progress.go): maps pi's --mode json
  NDJSON event stream to AgentEvent values. Handles session
  header (InitEvent), text, thinking, tool_result,
  message_end (TokensEvent), agent_end (ResultEvent), and
  error events. Detects stop_reason=error/aborted for the
  exit-0-override since --mode json exits 0 on model error.
  Falls back to synthesized ResultEvent on truncated streams.
- Test fixtures (testdata/pi/): recorded from pi 0.84.2
  --mode json output covering basic run, error run,
  reasoning, multi-step, malformed input, empty input, and
  truncated stream scenarios.
- Registry wiring: "pi" case in Resolve() switch.
- Documentation: pi column in docs/runtimes.md security
  feature matrix, config key support table, registered
  runtimes row, and pi-specific known constraints section.

Note: pre-commit could not run (sandbox network policy
blocked git fetch during hook environment init).
golangci-lint not available in sandbox. go vet passes.

Related to #6464
dhshah13 pushed a commit to dhshah13/fullsend that referenced this pull request Aug 24, 2026
Register PiRuntime (earendil-works/pi, CLI `pi`) in runtime.Resolve()
following the OpenCode stub precedent (fullsend-ai#6035): resolvable internally for
dev/testing, deliberately NOT added to config.ValidRuntimes() — a selectable
stub would burn pre-script side effects and a sandbox before failing — so it
is not user-selectable via `fullsend admin install --runtime` until the
runtime is functional.

- internal/runtime/pi.go: Name "pi", System "pi" (multi-provider, OpenCode
  precedent), ConfigDir /sandbox/pi-config (new sandbox.SandboxPiConfig,
  outside the agent-writable workspace), EnvExports pinning
  PI_CODING_AGENT_DIR / PI_CODING_AGENT_SESSION_DIR to runner-owned paths
  plus PI_OFFLINE=1 and PI_SKIP_VERSION_CHECK=1; Bootstrap/Run and
  transcript extraction return explicit not-implemented errors (fullsend-ai#6464).
- images/sandbox/Containerfile: ARG PI_VERSION=0.84.2, npm install
  --ignore-scripts, with a renovate customManagers regex tracking the pin;
  the install comment records that pin bumps must re-verify the upcoming
  stream-parser fixtures (pi changed its --mode json shape within 0.84).
- docs/runtimes.md: registered-runtimes row, pi (stub) column in the
  security feature matrix and the config-key support matrix.
- Tests: pi_test.go (metadata, env exports, not-implemented, no-ops,
  capability defaults — no CLAUDE.md bridge, default debug-log name);
  registry and config tests extended with the resolvable-but-not-selectable
  cases.

Next steps tracked in fullsend-ai#6464: stream parser with recorded fixtures,
Bootstrap/Run with the ADR 0090 hook-adapter extension, transcript
extraction, then ValidRuntimes() enable.

Refs fullsend-ai#6464

Assisted-by: Claude
Signed-off-by: Wayne Sun <gsun@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TranscriptHandler assumes file-based JSONL traces — needs format-neutral contract before second runtime

2 participants