pub trait HarnessAdapter {
Show 21 methods
// Required methods
fn label(&self) -> &'static str;
fn skills_dir(&self, repo_root: &Path) -> PathBuf;
fn rewrites_frontmatter_name(&self) -> bool;
fn advertises_staged_slug_name(&self) -> bool;
fn render_available_skills_block(&self, skills: &[AvailableSkill]) -> String;
fn skill_surface_phrase(&self) -> &'static str;
fn skill_unresolved_phrase(&self) -> &'static str;
fn plan_mode_profile(&self) -> &'static str;
fn parse_transcript(&self, path: &Path) -> Result<Vec<ToolInvocation>>;
fn parse_transcript_full(&self, path: &Path) -> Result<TranscriptSummary>;
fn install_guard(
&self,
stage_root: &Path,
guard_exe: &Path,
ttl: Option<Duration>,
) -> Result<PathBuf>;
// Provided methods
fn render_plan_mode_context(&self, profile_text: &str) -> String { ... }
fn runbook_template(&self) -> &'static str { ... }
fn cli_events_filename(&self) -> Option<&'static str> { ... }
fn cli_model_flag(&self) -> Option<&'static str> { ... }
fn cli_next_steps(&self, _ctx: CliDispatchContext<'_>) -> String { ... }
fn cli_manifest_section(
&self,
_ctx: CliManifestContext<'_>,
) -> Option<Vec<String>> { ... }
fn cli_judge_next_steps(&self, _ctx: CliJudgeContext) -> Option<String> { ... }
fn parse_cli_events(&self, path: &Path) -> Result<Vec<ToolInvocation>> { ... }
fn parse_cli_events_full(&self, path: &Path) -> Result<TranscriptSummary> { ... }
fn guard_armed_message(&self) -> Option<&'static str> { ... }
}Expand description
The behavior that varies by harness. Generic run-mode code depends on this trait, never on a concrete harness variant.
Required Methods§
Sourcefn label(&self) -> &'static str
fn label(&self) -> &'static str
The kebab-case identifier used in CLI flags, dispatch.json, and the
staged conditions.json.
Sourcefn skills_dir(&self, repo_root: &Path) -> PathBuf
fn skills_dir(&self, repo_root: &Path) -> PathBuf
The project-local directory staged skills live under for this harness.
Sourcefn rewrites_frontmatter_name(&self) -> bool
fn rewrites_frontmatter_name(&self) -> bool
Whether a staged skill’s frontmatter name: is rewritten to its slug so
the harness’s repo-local discovery resolves the staged copy.
Sourcefn advertises_staged_slug_name(&self) -> bool
fn advertises_staged_slug_name(&self) -> bool
Whether the skill-under-test is advertised in the available-skills block under its staged slug (vs. its natural name). True for Codex, whose repo-local discovery keys on the rewritten frontmatter name. (OpenCode also rewrites the frontmatter to the slug yet still advertises the natural name — a known inconsistency tracked for a separate fix.)
Sourcefn render_available_skills_block(&self, skills: &[AvailableSkill]) -> String
fn render_available_skills_block(&self, skills: &[AvailableSkill]) -> String
Render the discoverable skills the way this harness natively surfaces
them (e.g. Claude Code’s Skill-tool list, Codex’s ## Skills, OpenCode’s
<available_skills> XML).
Sourcefn skill_surface_phrase(&self) -> &'static str
fn skill_surface_phrase(&self) -> &'static str
How a staged skill is described as discoverable in the neutral slug-disambiguation line (e.g. “via the Skill tool”).
Sourcefn skill_unresolved_phrase(&self) -> &'static str
fn skill_unresolved_phrase(&self) -> &'static str
The lead-in for the fallback “read the skill from <path>” instruction
when the staged identifier can’t be resolved.
Sourcefn plan_mode_profile(&self) -> &'static str
fn plan_mode_profile(&self) -> &'static str
The verbatim plan-mode procedure profile bundled for this harness.
Sourcefn parse_transcript(&self, path: &Path) -> Result<Vec<ToolInvocation>>
fn parse_transcript(&self, path: &Path) -> Result<Vec<ToolInvocation>>
Parse a persisted transcript into its ordered tool invocations.
Sourcefn parse_transcript_full(&self, path: &Path) -> Result<TranscriptSummary>
fn parse_transcript_full(&self, path: &Path) -> Result<TranscriptSummary>
Parse a persisted transcript into the full summary: tool invocations, deduped token usage, duration, and final message text.
Sourcefn install_guard(
&self,
stage_root: &Path,
guard_exe: &Path,
ttl: Option<Duration>,
) -> Result<PathBuf>
fn install_guard( &self, stage_root: &Path, guard_exe: &Path, ttl: Option<Duration>, ) -> Result<PathBuf>
Arm the write guard using this harness’s native pre-tool hook surface,
returning the staged marker path. The guard’s allowed roots are derived
from stage_root (the isolated env / agent cwd), so it bounds the agent to
the same env boundary that isolates its reads.
Provided Methods§
Sourcefn render_plan_mode_context(&self, profile_text: &str) -> String
fn render_plan_mode_context(&self, profile_text: &str) -> String
Wrap a plan-mode profile as a <system-reminder> operating-context
layer. The default usually suffices.
Sourcefn runbook_template(&self) -> &'static str
fn runbook_template(&self) -> &'static str
The interactive (agent-followed) RUNBOOK.md template a harness uses
under InSession dispatch,
carrying {{TOKEN}} placeholders the run fills. The default is the shared
headless template (harmless for the Cli-only harnesses that never read it
via this path); InSession
harnesses override it. The Cli-dispatch runbook always uses
HEADLESS_RUNBOOK_TEMPLATE, selected by mechanism in build_runbook.
Sourcefn cli_events_filename(&self) -> Option<&'static str>
fn cli_events_filename(&self) -> Option<&'static str>
For a Cli-dispatch harness, the
filename (under a task’s outputs/ dir) its one-shot CLI writes the
transcript to. None when the harness dispatches in-session (no local
transcript) or has no Cli-mechanism transcript wired yet.
Sourcefn cli_model_flag(&self) -> Option<&'static str>
fn cli_model_flag(&self) -> Option<&'static str>
For a Cli-dispatch harness, the
native model-selection flag accepted by the harness CLI. None means the
adapter has no model-selection support wired yet.
Sourcefn cli_next_steps(&self, _ctx: CliDispatchContext<'_>) -> String
fn cli_next_steps(&self, _ctx: CliDispatchContext<'_>) -> String
The Next: guidance printed after run for a
Cli-dispatch harness: how to
dispatch each task through this harness’s one-shot CLI and then ingest.
Empty for in-session harnesses (their guidance is the mechanism’s, not the
adapter’s).
Sourcefn cli_manifest_section(
&self,
_ctx: CliManifestContext<'_>,
) -> Option<Vec<String>>
fn cli_manifest_section( &self, _ctx: CliManifestContext<'_>, ) -> Option<Vec<String>>
Extra dispatch-manifest.md lines describing this harness’s Cli dispatch
recipe (command template, parallel recipe, ingest note). None when the
harness contributes no Cli-specific manifest section.
Sourcefn cli_judge_next_steps(&self, _ctx: CliJudgeContext) -> Option<String>
fn cli_judge_next_steps(&self, _ctx: CliJudgeContext) -> Option<String>
The post-grade / post-ingest judge dispatch guidance for a
Cli-dispatch harness. None
leaves the generic in-session-style judge handoff in place.
Sourcefn parse_cli_events(&self, path: &Path) -> Result<Vec<ToolInvocation>>
fn parse_cli_events(&self, path: &Path) -> Result<Vec<ToolInvocation>>
Parse a Cli-mechanism events file
(the harness CLI’s captured output) into ordered tool invocations. Defaults
to parse_transcript: for Codex/OpenCode the
on-disk parser already is the events parser, so the default is correct;
Claude Code overrides it, because its parse_transcript is the in-session
subagent parser while its Cli events are claude -p stream-json.
Sourcefn parse_cli_events_full(&self, path: &Path) -> Result<TranscriptSummary>
fn parse_cli_events_full(&self, path: &Path) -> Result<TranscriptSummary>
The full-summary counterpart of parse_cli_events.
Sourcefn guard_armed_message(&self) -> Option<&'static str>
fn guard_armed_message(&self) -> Option<&'static str>
The banner printed after --guard successfully arms, describing the
harness’s native hook surface and how to remove it. Harness-specific text,
so it lives here rather than in generic run code. None for a harness with
no write guard (its install_guard errors), in which
case no banner is printed.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".