AGENT SKILL

goal-run

Methodology home for the goal-run harness (issue #874): the stage-machine contract, halt-reason precedence, launch arms, worktree lifecycle, the label-to-ledger join query for escape-rate segmentation, and the untrusted-content discipline for a single vendor-goal-loop harness run. Use when extending, halting, resuming, or documenting a /goal-run invocation, or when writing the escape-rate query that segments goal-run PRs from Code-Conductor-orchestrated PRs. DO NOT USE FOR: the live /goal-run execution prose itself (use agents/Goal-Run.agent.md, the shared body this skill is referenced from) or the goal-contract plan-authoring schema (use skills/plan-authoring's goal-contract schema, decision 872-D2).

License 许可
MIT
最近更新
2026-08-16
Stars
★ 3
Forks
0

01 前言 Front Matter

name
goal-run
description
Methodology home for the goal-run harness (issue #874): the stage-machine contract, halt-reason precedence, launch arms, worktree lifecycle, the label-to-ledger join query for escape-rate segmentation, and the untrusted-content discipline for a single vendor-goal-loop harness run. Use when extending, halting, resuming, or documenting a /goal-run invocation, or when writing the escape-rate query that segments goal-run PRs from Code-Conductor-orchestrated PRs. DO NOT USE FOR: the live /goal-run execution prose itself (use agents/Goal-Run.agent.md, the shared body this skill is referenced from) or the goal-contract plan-authoring schema (use skills/plan-authoring's goal-contract schema, decision 872-D2).

02 资源文件 2

03 SKILL.md 正文

<!-- markdownlint-disable-file MD041 MD003 -->

Goal-Run Harness

Reference methodology for the goal-run harness: a launcher/resumer that walks a single GitHub issue's approved goal-contract (a structured, machine-checkable target the vendor's own /goal loop runs against) through to a reviewed, classed pull request, without a human answering anything mid-run. This file documents the mechanics; the runnable prose lives in agents/Goal-Run.agent.md. For the invocation entry point and the reader-facing dual-flow orientation (conducted vs. goal-run, launch, resume, halt-reason reading guide, honest budget expectations), see CLAUDE.md § Orchestration and HOW-IT-WORKS.md § Goal-run: the unattended pipeline.

When to Use

  • When extending, debugging, or reviewing a change to the goal-run harness's stage machine, halt model, worktree lifecycle, or untrusted-content barriers.
  • When writing or reviewing the agents/Goal-Run.agent.md / agents/goal-run.md shared body and shell, or the customer-experience (CE) surface-class doc (skills/customer-experience/references/goal-run-surface-classes.md, 874-D8) and dual-flow guide that reference this skill.
  • When building the escape-rate segmentation query described in ## Label-To-Ledger Join.
  • When a reader needs to know what a goal-run-stage-{issue}, goal-run-inflight-{issue}, or goal-halt-report-{issue} marker means.

DO NOT USE FOR

  • Running /goal-run itself — that is agents/Goal-Run.agent.md (shared body) and agents/goal-run.md (Claude Code shell). This skill is the reference the body cites, not a substitute for it.
  • The goal-contract's own shape (targets, halt conditions, evidence obligations) — that schema lives under skills/plan-authoring/schemas/goal-contract.schema.json (872-D2).
  • General adversarial-review, CE Gate (Customer Experience Gate — the validation step confirming an implementation achieves the intended customer experience), or PR-persistence mechanics — the Post-Loop Chain (below) reuses adversarial-review, customer-experience, and persist-changes unchanged; load those skills directly for their own methodology.

Purpose

A goal-run invocation must survive a crash or a second concurrent launch attempt without losing track of where it is or double-provisioning a worktree. Every stage transition, halt, and terminal check is therefore read from durable GitHub artifacts — never from what a conversation remembers saying — and every function that makes one of these decisions is a tested PowerShell primitive under .github/scripts/lib/goal-run-*-core.ps1, not inline arithmetic in the agent prose.

Stage-Machine Contract

The stage-machine's WRITTEN marker vocabulary — the value actually persisted to the goal-run-stage-{Issue} comment — is a fixed four-value sequence ($script:GoalRunStageOrder in goal-run-stage-core.ps1):

pre-loop -> loop-launched -> loop-released -> chain-dispatched

pre-loop is the implicit starting state — no marker is ever posted for it on its own, and (M17 fix) the stage-marker writer's own ValidateSet excludes it, reconciling it against the reader's ExplicitStageMarker ValidateSet (Resolve-GoalRunResumeStage), which never accepted it either. A single <!-- goal-run-stage-{issue} --> issue comment is upserted in place (never appended-to) and always reflects the latest completed stage. This is deliberately the coarse top-level enum a resumed invocation switches on; finer-grained per-attempt history (why a run deviated, what it checkpointed) lives in the typed run log and the mutex marker, not here. Since the M10 fix, this marker also carries the provisioned worktree path (-WorktreePath on Set-GoalRunStageMarker), so a resuming invocation reads it directly off the marker instead of an undefined "most recent worktree" filesystem search.

Resolve-GoalRunResumeStage's returned .ResumeStage vocabulary is a superset of the four written values above: it adds a fifth, resolver-only value, loop-interrupted, that is never itself written to the stage marker — the function derives it purely from the durable signals below when an earlier session's loop-launched marker never reached loop-released. Resolve-GoalRunResumeStage decides where a resumed invocation re-enters, in this precedence (highest wins):

  1. Contract hash not verified against the launch-pinned value -> blocked (not a stage to execute — report and stop; the contract needs plan-side remediation).
  2. Terminal emissions already verified on a known PR -> complete (nothing left to do).
  3. Explicit stage marker is chain-dispatched or loop-released -> resume at chain-dispatched (the loop already released; only the chain remains).
  4. Explicit stage marker is loop-launched -> resolve to loop-interrupted, not literally loop-launched: a prior session launched the vendor loop and this resuming session has no live transcript to read a release verdict from, so the loop's true outcome must be reconstructed from durable state (see agents/Goal-Run.agent.md's ### loop-interrupted (resume without a transcript) section).
  5. No explicit marker, but the typed run log has a checkpoint/deviation/experience-observation entry -> also loop-interrupted, for the same reason — the loop ran even though no explicit marker was ever written (e.g. a crash between launch and the next marker).
  6. goal-run-active.json exists but no run-log evidence -> loop-launched — the worktree was provisioned but the loop itself was never launched.
  7. A mutex marker exists but nothing else -> pre-loop (crash mid pre-loop).
  8. Nothing present -> pre-loop (fresh launch).

blocked and complete are terminal reports, not stages a resumer executes — report and stop. loop-interrupted, unlike those two, IS a stage a resumer executes: its stage-machine section re-validates the committed worktree state directly, then either discovers the interrupted loop's work was already satisfied, relaunches the loop in the same worktree if it is genuinely dead, or reports a still-live run under a different session — it never just reports and stops.

Halt Model And Precedence

A halt report is a closed, five-value-enum object validated against skills/goal-run/schemas/goal-halt-report.schema.json (additionalProperties: false — every field the harness or an executor can populate is named and typed). The halt_reason enum is reused verbatim from the goal-contract schema's halt_conditions (872-D2): unachievable-target, invariant-conflict, budget-exhausted, gate-input-needed, chain-stage-failure.

When more than one halt condition is true at the same evaluation point, Resolve-GoalRunHaltPrecedence (goal-run-chain-core.ps1) picks the single winner by this total, non-negotiable order (highest wins):

invariant-conflict > unachievable-target > gate-input-needed > budget-exhausted > chain-stage-failure

This ordered list is the entire precedence rule; nothing else in the file overrides it. Resolve-GoalRunHaltPrecedence does not itself decide whether a condition is true — each producer's own detection lives elsewhere (the launch-pinned contract-hash mismatch and an executor's own halt-claim for invariant-conflict; the re-validation disposition, the fix-cycle cap, or a stage crash for chain-stage-failure; the wall-clock backstop for budget-exhausted; the chain-gate demand for gate-input-needed) — callers pass in the already-decided booleans.

A single-condition halt (nothing else co-occurring, e.g. the loop-released bounded-retry exhaustion) skips Resolve-GoalRunHaltPrecedence entirely and goes straight to the report builder — the precedence function only matters when two or more producers are simultaneously true.

Never hand-build a halt comment. New-GoalRunChainHaltReport composes the schema-shaped object (running every free-text field through secret redaction, below); Invoke-GoalRunHaltEmit (goal-run-halt-core.ps1) schema-validates and refuses to post an invalid report.

Launch Arms

Arm I (in-session) — the only arm implemented in this PR

/goal-run {issue} is both launcher and resumer. The harness verifies the contract hash, posts a mutex marker (goal-run-inflight-{issue}) before provisioning any worktree so a running worktree with no live marker can never exist, tiebreaks a concurrent launch race by lowest comment id, then sets the goal on itself and becomes the executor inside the freshly provisioned worktree. When the vendor /goal loop completes and control genuinely returns to the harness session, it reads the now-flushed goal_status verdict and enters the Post-Loop Chain (re-validate, CE Gate, adversarial review, capped fix cycles, PR creation with classing — see agents/Goal-Run.agent.md ## Post-Loop Chain for the full stage-by-stage prose).

The loop-to-chain seam is deliberately built from durable artifacts only: New-GoalRunExecutorSessionHandle and Invoke-GoalRunLaunchChain take an issue number, repo root, contract hash, worktree path, and a session handle — never live conversation context — so a future arm can populate the same shapes without rewriting this transition.

Arm H (headless) — PR-2, not yet implemented

A future PR will let the harness supervise an externally polled claude -p process instead of running in-session. The loop-to-chain seam above is already shaped to accept this without a rewrite. No further design decisions have been made yet; do not invent Arm H behavior beyond this pointer.

Arm M (manual hand-off) — PR-2, not yet implemented

A future PR will define a manual two-block rendering surface for a human to hand off a run. This PR renders no Arm M output and accepts no scope_boundaries prompt field. No further design decisions have been made yet; do not invent Arm M behavior beyond this pointer.

Worktree Lifecycle

All worktree mechanics live in goal-run-worktree-core.ps1; its own header comment is the authoritative function-by-function summary — this section is a pointer, not a re-derivation.

  • Provision — New-GoalRunWorktree refuses a dirty tree first, then creates a named branch goal-run/issue-{N}-{token} ({token} is a GUID-style collision-proof suffix, so two concurrent runs for the same issue never collide) at a short root outside the checkout, setting core.longpaths at worktree add.
  • State file — New-GoalRunActiveState writes goal-run-active.json at the worktree root: ceilings, baseline, arm, executor session id, the launch-pinned contract_hash, launched_at, a heartbeat_at timestamp (seeded equal to launched_at), and teardown_deferred (default false). Get-GoalRunActiveState reads it back and returns $null on a missing file rather than throwing. Update-GoalRunActiveStateHeartbeat refreshes heartbeat_at — wired live (M5 fix) via Invoke-GoalRunChainStageBoundaryHousekeeping (goal-run-budget-core.ps1) at every chain-stage boundary and at the loop-release point; before that fix the function existed and was tested but had zero live callers.
  • Run log — goal-run-log.jsonl at the worktree root (alongside goal-run-active.json), one JSON object per line, each independently validated against schemas/goal-run-log.schema.json before it is appended. Add-GoalRunLogEntry (goal-run-log-core.ps1, M9 fix) is the schema-validating writer; Test-GoalRunLogHasCheckpoint is the reader Resolve-GoalRunResumeStage's -RunLogHasCheckpoint parameter is actually fed from (Invocation Contract step 3). A checkpoint entry is written at every chain-stage boundary via the same Invoke-GoalRunChainStageBoundaryHousekeeping call named above.
  • Teardown — Remove-GoalRunWorktree retries git worktree remove with backoff on every exit path and diagnoses the outcome honestly across the same six-value vocabulary used by the session-startup cleanup detector: removed, removed-partial-root-held, removed-partial-content-remains, stale-registration, failed, verification-indeterminate. On retry exhaustion it sets teardown_deferred: true on the state file (best-effort) rather than throwing. It never force-removes a locked worktree on a prunable porcelain flag alone — only on Test-Path-verified absence of the directory, because real git never sets prunable on a locked worktree.

Label-To-Ledger Join (874-D7)

Every goal-run PR carries two machine-readable markers of its own provenance, both written at PR-creation time by Invoke-GoalRunClassEmission (goal-run-chain-core.ps1):

  • The goal-run GitHub PR label, applied by Add-GoalRunPrLabel.
  • A goal_run_class scalar field (default value goal-run) plus a goal_run_issue field, folded into the PR body's <!-- pipeline-metrics --> block through the existing Invoke-PipelineMetricsV4Emit primitive. Both fields are additive-safe: a reader that does not know about them silently ignores them.

The join key is goal_run_class (or, equivalently, the goal-run label) on the PR side. A future escape-rate query segments the frame-credit-ledger's per-PR review-defect counts by joining on that key: PRs where goal_run_class == 'goal-run' (or carrying the goal-run label) are goal-run-produced; every other PR in the ledger is Code-Conductor-orchestrated. No query tool exists yet — this section documents the join key and the intended analysis shape (per-PR defect count grouped by goal-run vs. non-goal-run) so a future maintainer can write it directly against the ledger and gh pr list --label goal-run without re-deriving which field to key on.

Untrusted-Content Discipline (M4/M5/M12)

Three separate guardrails stand between content the harness does not fully trust — a transcript event, a live issue comment that could have been edited after launch, or executor-supplied evidence text — and any durable artifact the harness writes:

  • Launch-pinned contract-hash check (step 5, wired live by the M1 fix) — Test-GoalRunContractHashPinned (goal-run-prompt-core.ps1) compares the live issue-body contract hash against the hash pinned at launch time, not the contract's own self-reported contract_hash field — this catches a post-approval edit that kept its own field internally consistent. A mismatch is the highest-precedence halt producer, invariant-conflict. Three live call sites actually run this check: the vendor /goal loop predicate (goal-run-predicate.ps1 / goal-run-predicate-core.ps1, on every loop iteration, via Resolve-GoalRunLoopPredicate), chain re-validation (Invoke-GoalRunChainRevalidate's -LaunchPinnedHash parameter, goal-run-chain-core.ps1), and resume-time verification (the agents/Goal-Run.agent.md Invocation Contract step 1). Before the M1 fix, the function existed and was tested but had zero live callers.
  • Transcript allow-list + secret-redaction pass (step 1) — Select-GoalRunAllowedFields (goal-run-transcript-core.ps1) copies only explicitly named keys out of a raw transcript event and also rejects a nested dictionary or non-string enumerable found under an allow-listed key name, so a poisoned event cannot smuggle structured content in under a trusted key. Get-GoalRunRedactedText then runs a fixed set of secret-shaped regexes (GitHub/AWS/Slack tokens, PEM private-key blocks, bearer tokens, generic key=value secret assignments) over any string headed for a durable artifact, replacing each match with a [REDACTED:<pattern-name>] placeholder.
  • Executor-evidence inert-render discipline (step 1) — ConvertTo-GoalRunInertEvidenceText (goal-run-halt-core.ps1) strips marker-delimiter substrings out of evidence[]/plan_remediation text before a halt report is posted, so executor-authored text cannot smuggle a live <!-- ... --> marker literal into a durable comment. Invoke-GoalRunHaltEmit applies this and schema-validates before ever posting — it is never bypassed by constructing a raw comment string.

Any transcript-derived or executor-supplied string reaching a halt report or a PR body fragment must already have passed through the allow-list extractor and the redaction pass; the halt-report schema's closed shape (additionalProperties: false) cannot itself enforce that upstream discipline, only the field shape.

Gotchas

Trigger Gotcha Fix
Polling stream-json stdout for the loop's release verdict goal_status is transcript-only and never reaches stream-json stdout on either platform (goal-loop-capability-probe finding) — a harness watching stdout is blind to release Only read the verdict after control genuinely returns to the harness session, via Resolve-GoalRunControlReturn's bounded transcript retry
Calling Resolve-GoalRunHaltPrecedence on every halt The function only matters when two or more of the five producers are true at once A single-condition halt (e.g. loop-released retry exhaustion) goes straight to the report builder
Assuming a chain-dispatched marker on resume means work remains A PR that already carries both the goal-run label and the classing metrics is genuinely complete Call Test-GoalRunPrEmissionsVerified against the run's known PR before assuming any work remains

Release-Hygiene Note

This file and its schemas/*.json siblings sit under skills/*, one of the bare glob patterns Get-FVPluginEntryPointPatterns (frame-predicate-core.ps1) classifies as a cache-keyed plugin entry point — any path under skills/** counts, not just files with a sibling SKILL.md. Claude Code's plugin cache is keyed by the version in .claude-plugin/plugin.json; a same-version reinstall keeps serving whatever entry-point snapshot that version last had. This file is a new entry point added after this PR's step-4 version bump already landed, so it requires its own coalesced bump-version.ps1 bump — see this step's dispatch report for the resulting version.

04 同仓库更多 Skills

Grimblaz
Grimblaz/agent-orchestra

webapp-testing

Playwright end-to-end testing guidance for web apps, with practical patterns and setup steps. Use when creating or improving browser-based E2E coverage, test stability, and CI execution. DO NOT USE FOR: React component tests (use ui-testing), canvas game interaction (use browser-canvas-testing), TDD workflow (use test-driven-development), debugging failures (use systematic-debugging), or randomized property tests (use property-based-testing).

测试与质量前端开发
★ 3
Grimblaz
Grimblaz/agent-orchestra

verification-before-completion

Evidence-based verification checklist before marking work complete. Use before PRs, releases, marking tickets done, or any "I'm finished" declaration; also when naming a baseline commit for a differential suite claim, when designing a mutation campaign or red-run evidence, when making an absence claim, a universal claim, or a one-time demonstration offered as a standing guarantee, when attributing a measurement or claiming a sweep or verification loop is complete, and when stating what a check or a CI suite will do about a change. DO NOT USE FOR: post-merge cleanup or archival (use post-pr-review) or processing GitHub review comments (use code-review-intake).

★ 3
Grimblaz
Grimblaz/agent-orchestra

validation-methodology

Reusable validation and review methodology for staged validation, failure triage, and prosecution-depth setup. Use when running validation ladders, triaging failures, or executing adversarial review passes. DO NOT USE FOR: CE Gate orchestration, specialist dispatch ownership, or step execution flow (keep those in Code-Conductor).

★ 3
Grimblaz
Grimblaz/agent-orchestra

upstream-onboarding

Shared opening-phase protocol for upstream agents (Experience-Owner, Solution-Designer, Issue-Planner) and Code-Conductor when invoked on an existing GitHub issue. Renders a scaled context brief and runs a standards check on inherited work at each phase boundary. Use when a user-invocable agent receives a request referencing an existing GitHub issue and must load solution-authoring and upstream-onboarding at the opening phase. DO NOT USE FOR: subagent dispatches (which already operate within an assessed session context); post-merge review (use post-pr-review); research or non-tree subagents.

人力资源Skill与智能体开发
★ 3
Grimblaz
Grimblaz/agent-orchestra

ui-testing

Resilient React component testing strategies focusing on user behavior. Use when writing or reviewing component-level React tests, fixing flaky component tests, or establishing React testing patterns. DO NOT USE FOR: Playwright E2E tests (use webapp-testing), canvas game interaction (use browser-canvas-testing), TDD workflow (use test-driven-development), debugging failures (use systematic-debugging), UI component design (use frontend-design), or randomized property tests (use property-based-testing).

设计师测试与质量前端开发
★ 3
Grimblaz
Grimblaz/agent-orchestra

ui-iteration

Reusable screenshot-driven UI polish workflow for iterative visual refinement. Use when improving layout, hierarchy, spacing, feedback, or Tailwind-based presentation through repeated review-and-adjust passes. DO NOT USE FOR: functional bug fixing, accessibility-only audits, or major redesign strategy work (use Code-Smith or frontend-design).

设计师前端开发
★ 3