feat: add gpd:goal — goal-directed autonomous runs under binding caps - #254
feat: add gpd:goal — goal-directed autonomous runs under binding caps#254hvgazula wants to merge 15 commits into
Conversation
- Dual cap (USD + max-phases): Claude Code emits no cost telemetry, so the USD budget binds only where cost_usd is available (codex today); the phase cap binds everywhere; fail closed when neither is enforceable - Criteria reference plan-contract claim ids, aggregated from VERIFICATION.md contract_results.claims (existing verifier machinery) instead of a nonexistent per-check surface - Separate workflows/goal/ workflow; autonomous stage manifest untouched (topology tests forbid edits) - Typed goal_contract field on ResearchState; validator precedent corrected to review-ledger/referee-decision (JSON+pydantic) - Generated-surface regen (repo graph, public surface, help surface) added to scope
- strict_criteria fallback knob (claim-id threading robustness; fail still blocks) - explicit max-phases-N-permits-N semantics (wrap_up = one final consolidation phase) - Task 6 end-to-end gate-plumbing smoke test (demo floor) - minimal-demoable-slice note; USD-on-codex marked unverified stretch
|
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
✅ Files skipped from review due to trivial changes (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds a typed goal-contract in state, evidence aggregation from phase VERIFICATION.md files, dual-cap gating and criteria evaluation, CLI commands ( ChangesGoal Command Feature
Sequence DiagramsequenceDiagram
participant CLI as gpd CLI
participant State as GPD/state.json
participant Evidence as goal_evidence
participant Gate as goal_gate
CLI->>State: load goal_contract
CLI->>Evidence: collect_claim_outcomes & collect_phase_statuses
CLI->>Gate: goal_gate_summary(contract, spent_usd, claim_outcomes)
Gate-->>CLI: GoalGateSummary JSON
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🤖 RoastBot: Capitalism has arrived in the agent loop. The AI now has KPIs and hard stops. We've given it ambition and a performance review. |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (3)
tests/core/test_goal_evidence.py (1)
5-5: 💤 Low valueConsolidate imports at module level for consistency.
collect_phase_statusesis imported locally within two test functions (lines 69, 79), whilecollect_claim_outcomesis imported at the module top (line 5). For consistency and clarity, import both functions at the module level.♻️ Consolidate imports
-from gpd.core.goal_evidence import collect_claim_outcomes +from gpd.core.goal_evidence import collect_claim_outcomes, collect_phase_statusesThen remove the local imports at lines 69 and 79.
Also applies to: 69-69, 79-79
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/core/test_goal_evidence.py` at line 5, The tests import collect_claim_outcomes at module level but import collect_phase_statuses inside individual test functions; move the local imports of collect_phase_statuses up to the module-level imports alongside collect_claim_outcomes, and then remove the redundant local import statements inside the two test functions so both helpers (collect_claim_outcomes and collect_phase_statuses) are imported consistently at the top of the test module.tests/core/test_cli_goal.py (2)
48-57: ⚡ Quick winConsider strengthening the validation assertion.
Line 57 checks only for
"max_phases"in the issues when both caps areNone. Since the validation rule is "at least one cap is required" (pergoal.mdline 37), the assertion is somewhat arbitrary. If the validation error mentionsbudget_usdinstead, or uses a more general message, the test could become brittle.💡 More robust assertion
- assert any("max_phases" in issue for issue in payload["issues"]) + # Check that the validation caught the missing cap requirement + assert any("max_phases" in issue or "budget_usd" in issue or "at least one cap" in issue.lower() + for issue in payload["issues"])🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/core/test_cli_goal.py` around lines 48 - 57, The test test_validate_goal_contract_reports_issues is brittle because it asserts only that "max_phases" appears in payload["issues"]; update the assertion to check for the required-cap validation more robustly by verifying that payload["valid"] is False and that payload["issues"] contains either a mention of "max_phases" or "budget_usd" or a phrase indicating the "at least one cap" rule (use the existing runner.invoke/app/_raw_payload_from_result flow to locate the payload and adjust the final assertion accordingly so it accepts either specific field names or a general cap-related message).
80-86: ⚡ Quick winError message assertion aligns with the actual fail-closed text (optional robustness tweak).
GoalGateErroris raised with: “... no max_phases cap is set. Set --max-phases ...”, and the CLI forwardsstr(exc)as the--rawJSON{"error": ...}payload.- Optional: assert on the more semantic
"No enforceable cap"substring instead ofmax-phases/max_phasesto avoid coupling to wording/flag formatting.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/core/test_cli_goal.py` around lines 80 - 86, Update the assertion in test_goal_gate_fails_closed_without_enforceable_cap to check the semantic failure message rather than flag formatting: after invoking runner.invoke(app, ["--raw", "--cwd", str(tmp_path), "goal", "gate"]) assert that the combined output contains the lowercased semantic substring "no enforceable cap" (e.g. assert "no enforceable cap" in combined) and you may keep the existing fallback that checks for "max-phases"/"max_phases" if desired; this targets the GoalGateError message forwarded by the CLI when no max_phases cap is set and avoids coupling to flag formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/plans/2026-06-04-goal-command.md`:
- Line 7: Update the documentation phrase "gpd goal typer sub-app" to use the
correct product name by capitalizing Typer (i.e., "gpd goal Typer sub-app");
locate the string near the description referencing the gpd goal sub-app and
change "typer" to "Typer" so the docs consistently use the proper framework name
alongside symbols like goal_contract.py, goal_gate.py, and goal_evidence.py.
- Line 42: The markdown heading "### Task 1: Goal contract models and state
field" jumps from a level 1 heading to level 3 (violates MD001); change that
heading to a level 2 heading ("## Task 1: Goal contract models and state field")
or adjust surrounding headings so levels increment by one, ensuring the document
follows proper hierarchy and TOC parsers can correctly render sections.
In `@docs/superpowers/specs/2026-06-04-goal-command-design.md`:
- Around line 61-67: The fenced command block containing the example commands
(starting with "/gpd:goal \"Derive the dispersion relation..." and including
lines like "gpd goal status" and "gpd validate goal-contract") lacks a language
tag and triggers MD040; update the opening fence from ``` to ```bash (or
```text) so the block is labeled (e.g., ```bash) to satisfy markdownlint and
docs tooling.
In `@README.md`:
- Around line 534-535: Add two CLI reference entries for the missing
runtime-status commands alongside the existing validate lines: include `gpd goal
status [<goal-id>] [--watch]` with a short description like "Show runtime status
and metadata for a goal (optionally watch updates)" and `gpd goal gate <goal-id>
[--approve|--reject] [--reason]` with a description like "Inspect and act on
goal gates (approve/reject with optional reason)"; place these lines next to the
`gpd validate goal-contract` and `gpd validate reproducibility-manifest` rows in
the CLI table and mirror the style/flag notation used for other commands so
users see the full runtime-status surface.
In `@src/gpd/cli.py`:
- Around line 4495-4498: Replace the hard-coded "/gpd:goal" in the _error call
with the runtime-aware public command helper so the hint points to the correct
command surface; update the call in the block that calls _error (the missing
contract branch) to build the command text via the runtime/public-command helper
(e.g., use the project's runtime.public_command or get_public_command utility
with "gpd:goal") and interpolate that into the hint string along with the
existing flags and example usage.
- Around line 4504-4515: The current all_phases_passed uses
collect_phase_statuses(cwd) which returns project-wide phases and can include
unrelated failed phases; scope the phase statuses to the active goal run before
computing the boolean. Update either collect_phase_statuses (or filter its
returned dict) to accept and use the active run identifier from the current
contract (e.g., contract.run_id or contract metadata) so you only keep phases
belonging to that run, then compute all_phases_passed from that filtered set and
pass it into goal_gate_summary (symbols: collect_phase_statuses, contract,
all_phases_passed, goal_gate_summary). Ensure the filtering uses the run-scoped
field present in the contract/run state and preserves existing behavior when no
run id is available.
- Around line 4489-4505: The code uses _get_cwd() which can point to a nested
dir; change the logic in _goal_gate_payload() to resolve the repository/project
root first and use that for all reads: replace cwd = _get_cwd() with a call to
the project-root resolver used elsewhere (e.g. _get_project_root() or
_resolve_project_root()) and then pass that resolved_root to
state_load_readonly(...), build_cost_summary(...), collect_claim_outcomes(...),
and collect_phase_statuses(...) so the command always inspects the project root
state.json and related data.
In `@src/gpd/core/state.py`:
- Line 505: The normalization currently auto-heals nested GoalContract errors by
iteratively removing failing `loc` paths via
`_remove_validation_error_path(...)` in `_normalize_state_schema`; update
`_salvage_state_sections` (or the `_normalize_state_schema` recovery loop) to
special-case `goal_contract` (ResearchState.goal_contract) the same way
`project_contract` is handled: when a PydanticValidationError references any
`goal_contract` path, do not prune individual nested keys—either surface the
validation failure (raise/return an explicit integrity error) or drop the entire
`goal_contract` object and emit an integrity finding describing the drop; ensure
references to `GoalContract` and the failing `loc` are preserved in the finding
so callers can detect and fail-closed.
In `@src/gpd/specs/templates/state-json-schema.md`:
- Line 36: The JSON-only authority list is missing the newly introduced
top-level field goal_contract; update the authority list later in the document
to include `goal_contract` as an authoritative JSON-only entry (matching the
table row: `goal_contract | GoalContract | null`) so merge/recovery semantics
remain consistent; locate references to the JSON-only authority list and add
`goal_contract` to that list alongside the other JSON-only fields.
---
Nitpick comments:
In `@tests/core/test_cli_goal.py`:
- Around line 48-57: The test test_validate_goal_contract_reports_issues is
brittle because it asserts only that "max_phases" appears in payload["issues"];
update the assertion to check for the required-cap validation more robustly by
verifying that payload["valid"] is False and that payload["issues"] contains
either a mention of "max_phases" or "budget_usd" or a phrase indicating the "at
least one cap" rule (use the existing runner.invoke/app/_raw_payload_from_result
flow to locate the payload and adjust the final assertion accordingly so it
accepts either specific field names or a general cap-related message).
- Around line 80-86: Update the assertion in
test_goal_gate_fails_closed_without_enforceable_cap to check the semantic
failure message rather than flag formatting: after invoking runner.invoke(app,
["--raw", "--cwd", str(tmp_path), "goal", "gate"]) assert that the combined
output contains the lowercased semantic substring "no enforceable cap" (e.g.
assert "no enforceable cap" in combined) and you may keep the existing fallback
that checks for "max-phases"/"max_phases" if desired; this targets the
GoalGateError message forwarded by the CLI when no max_phases cap is set and
avoids coupling to flag formatting.
In `@tests/core/test_goal_evidence.py`:
- Line 5: The tests import collect_claim_outcomes at module level but import
collect_phase_statuses inside individual test functions; move the local imports
of collect_phase_statuses up to the module-level imports alongside
collect_claim_outcomes, and then remove the redundant local import statements
inside the two test functions so both helpers (collect_claim_outcomes and
collect_phase_statuses) are imported consistently at the top of the test module.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 2e1e30ec-85d5-485b-b8d4-806cfa56fa82
📒 Files selected for processing (21)
CONTRIBUTING.mdREADME.mddocs/superpowers/plans/2026-06-04-goal-command.mddocs/superpowers/specs/2026-06-04-goal-command-design.mdsrc/gpd/cli.pysrc/gpd/commands/goal.mdsrc/gpd/core/goal_contract.pysrc/gpd/core/goal_evidence.pysrc/gpd/core/goal_gate.pysrc/gpd/core/state.pysrc/gpd/specs/references/help/detailed-command-reference.mdsrc/gpd/specs/templates/state-json-schema.mdsrc/gpd/specs/workflows/goal/goal-bootstrap.mdsrc/gpd/specs/workflows/help.mdtests/README.mdtests/core/test_cli_goal.pytests/core/test_goal_contract.pytests/core/test_goal_evidence.pytests/core/test_goal_gate.pytests/core/test_goal_smoke.pytests/repo_graph_contract.json
| claim_outcomes = collect_claim_outcomes(cwd) | ||
| phase_statuses = collect_phase_statuses(cwd) | ||
| all_phases_passed = bool(phase_statuses) and all( | ||
| status == "passed" for status in phase_statuses.values() | ||
| ) | ||
| try: | ||
| summary = goal_gate_summary( | ||
| contract, | ||
| spent_usd=spent_usd, | ||
| claim_outcomes=claim_outcomes, | ||
| all_phases_passed=all_phases_passed, | ||
| ) |
There was a problem hiding this comment.
Scope phase verdicts to the active goal run before gating.
collect_phase_statuses(cwd) appears to scan the whole GPD/phases tree, and this code collapses every returned status into one all_phases_passed flag. That means an old failed verification elsewhere in the project can keep a brand-new goal permanently unachievable even when this goal's own criteria are satisfied. The gate needs a run-scoped phase set/window from the goal contract or run state before computing this boolean.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/gpd/cli.py` around lines 4504 - 4515, The current all_phases_passed uses
collect_phase_statuses(cwd) which returns project-wide phases and can include
unrelated failed phases; scope the phase statuses to the active goal run before
computing the boolean. Update either collect_phase_statuses (or filter its
returned dict) to accept and use the active run identifier from the current
contract (e.g., contract.run_id or contract metadata) so you only keep phases
belonging to that run, then compute all_phases_passed from that filtered set and
pass it into goal_gate_summary (symbols: collect_phase_statuses, contract,
all_phases_passed, goal_gate_summary). Ensure the filtering uses the run-scoped
field present in the contract/run state and preserves existing behavior when no
run id is available.
There was a problem hiding this comment.
Partially agree, leaving this open as a design follow-up rather than fixing it in this PR. Two mitigating points on severity: (1) all_phases_passed only feeds the non-default strict_criteria: false fallback, and that fallback can only promote pending criteria (missing claim evidence) to pass — criteria with real contract_results.claims evidence achieve the goal regardless of this flag. (2) The failure direction is conservative: a stale failed phase makes the fallback unavailable, so the run ends budget_stopped instead of wrongly achieved — it never overclaims. Properly run-scoping the boolean needs a phase-set snapshot recorded in the goal contract at bootstrap (a schema addition), which is a design decision for the author rather than a review fix. Until then, projects with pre-existing failed phases simply can't use the non-strict demo fallback.
There was a problem hiding this comment.
@hvgazula, that’s a fair distinction. Given that all_phases_passed only affects the non-default strict_criteria: false fallback and fails conservatively, I agree this is not a correctness blocker for this PR. The remaining concern is better framed as a design/UX follow-up for demo fallback behavior, not a major review fix.
Would you like me to open a GitHub issue to track the run-scoped phase-set snapshot/schema addition for a future PR?
( (\/)
(••) thoughtfully noted )
✏️ Learnings added
Learnt from: hvgazula
Repo: psi-oss/get-physics-done PR: 254
File: src/gpd/cli.py:4511-4522
Timestamp: 2026-06-05T13:10:40.063Z
Learning: In `src/gpd/cli.py`, the `gpd goal gate/status` `all_phases_passed` boolean only affects the non-default `GoalContract.strict_criteria = false` fallback; strict verifier-gated criteria based on `contract_results.claims` can achieve a goal independently of this flag.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
…w stem, category, budgets) - Replace literal /gpd:goal slash form with runtime-neutral gpd:goal in cli.py error string and goal-bootstrap.md (runtime-abstraction boundary) - Add top-level workflows/goal.md compatibility index so goal is workflow-backed - Register gpd-goal -> execution in registry skill-category map - Add measured COMMAND_BASELINES/WORKFLOW_BASELINES entries for goal - Regenerate repo-graph contract + tests/README for the new workflow stem Resolves 10 of 16 goal-registration suite failures; 6 runtime-projection budget failures remain.
…and; wire goal command to same-stem index Adding gpd:goal nudges several full-registry runtime-projection ceilings up by one skill/command's worth of fixed-template pressure. Ratchet the advisory budgets to just above the measured values: - codex per-skill runtime-note aggregate cap 25_000 -> 26_000 (one more fixed-template note; cannot be compacted). - COMMAND_ONLY_RUNTIME_PRESSURE_BUDGETS bridge_command_occurrences: codex 245 -> 251, copilot-cli 174 -> 179, opencode 174 -> 179 (goal's five gpd --raw snippets + auto-injected runtime note; Option B per the investigation — Option A cannot reach the budget since the injected note is mandatory). - compare-experiment codex 7_700 -> 7_800, gemini 8_400 -> 8_500 (base dict). - explain codex 6_150 -> 6_200 (both ADDITIONAL dicts); explain copilot-cli 6_470 -> 6_550 in the diagnostics-budget dict. Also cross-link the goal command to its same-stem compatibility index via an inline (non-@) reference so test_commands_reference_same_stem_workflows passes without expanding the index or adding bridge/shell pressure.
e96947e to
1e79725
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (3)
docs/superpowers/plans/2026-06-04-goal-command.md (2)
42-42:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix heading level increment for markdown structure.
Line 42 jumps from
#to###without an intermediate##, which violates MD001 and can break TOC/section parsing in some renderers.🧰 Proposed fix
--- -### Task 1: Goal contract models and state field +## Task 1: Goal contract models and state field **Files:**🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-06-04-goal-command.md` at line 42, The markdown heading at "### Task 1: Goal contract models and state field" jumps from a top-level "#" to "###", breaking heading sequence; change that heading to "## Task 1: Goal contract models and state field" (or adjust the preceding top-level heading to include an intermediate "##" section) so headings follow the expected incremental levels and satisfy MD001/TOC parsers.
7-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winCapitalize the framework name
Typer."typer sub-app" should be "Typer sub-app" for correct product naming and doc polish.
🧰 Proposed fix
-**Architecture:** Pure-Python core modules hold the typed goal contract (`goal_contract.py`), the dual-cap gate + criteria decisions (`goal_gate.py`), and the VERIFICATION.md claim-outcome aggregator (`goal_evidence.py`). A typed `goal_contract` field is added to `ResearchState` (mirroring `project_contract`). A `gpd goal` typer sub-app exposes `status` and `gate`; `gpd validate goal-contract` follows the JSON+pydantic validator pattern of `review-ledger`/`referee-decision`. A new `goal.md` command descriptor delegates to its own `workflows/goal/goal-bootstrap.md` (the `autonomous` workflow and its stage manifest are NOT modified — its topology tests forbid that). No staged-init registration in v1. +**Architecture:** Pure-Python core modules hold the typed goal contract (`goal_contract.py`), the dual-cap gate + criteria decisions (`goal_gate.py`), and the VERIFICATION.md claim-outcome aggregator (`goal_evidence.py`). A typed `goal_contract` field is added to `ResearchState` (mirroring `project_contract`). A `gpd goal` Typer sub-app exposes `status` and `gate`; `gpd validate goal-contract` follows the JSON+pydantic validator pattern of `review-ledger`/`referee-decision`. A new `goal.md` command descriptor delegates to its own `workflows/goal/goal-bootstrap.md` (the `autonomous` workflow and its stage manifest are NOT modified — its topology tests forbid that). No staged-init registration in v1.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-06-04-goal-command.md` at line 7, The doc uses lowercase "typer" for the CLI framework; change occurrences to the proper product name "Typer" (e.g., in the phrase "gpd goal typer sub-app" make it "gpd goal Typer sub-app") and similarly update any other mentions in this paragraph (references around goal_contract.py, goal_gate.py, goal_evidence.py, the `gpd goal` sub-app and `gpd validate goal-contract` command descriptions) to use the capitalized "Typer". Ensure only the product name casing is changed and no other wording is altered.docs/superpowers/specs/2026-06-04-goal-command-design.md (1)
61-67:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a language tag to the fenced command block.
The fenced block is unlabeled, which trips markdownlint (MD040). Use
bashortextfor consistency with docs tooling.🧰 Proposed fix
-``` +```bash /gpd:goal "Derive the dispersion relation for X and verify the long-wavelength limit" --budget-usd 5 --max-phases 6 /gpd:goal --resume [--budget-usd 8] [--max-phases 10] gpd goal status # terminal receipt: spend, phases, criteria, status gpd goal gate # machine decision the run loop shells out to (--raw) gpd validate goal-contract <file.json|-> # typed validation surface</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@docs/superpowers/specs/2026-06-04-goal-command-design.mdaround lines 61 -
67, The fenced command block in
docs/superpowers/specs/2026-06-04-goal-command-design.md is missing a language
tag (triggering MD040); update the opening triple-backtick for the block that
contains the /gpd:goal, gpd goal status, gpd goal gate, and gpd validate
goal-contract examples to include a language such as bash (e.g., ```bash) so the
block is labeled for markdownlint and docs tooling.</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.Duplicate comments:
In@docs/superpowers/plans/2026-06-04-goal-command.md:
- Line 42: The markdown heading at "### Task 1: Goal contract models and state
field" jumps from a top-level "#" to "###", breaking heading sequence; change
that heading to "## Task 1: Goal contract models and state field" (or adjust the
preceding top-level heading to include an intermediate "##" section) so headings
follow the expected incremental levels and satisfy MD001/TOC parsers.- Line 7: The doc uses lowercase "typer" for the CLI framework; change
occurrences to the proper product name "Typer" (e.g., in the phrase "gpd goal
typer sub-app" make it "gpd goal Typer sub-app") and similarly update any other
mentions in this paragraph (references around goal_contract.py, goal_gate.py,
goal_evidence.py, thegpd goalsub-app andgpd validate goal-contract
command descriptions) to use the capitalized "Typer". Ensure only the product
name casing is changed and no other wording is altered.In
@docs/superpowers/specs/2026-06-04-goal-command-design.md:
- Around line 61-67: The fenced command block in
docs/superpowers/specs/2026-06-04-goal-command-design.md is missing a language
tag (triggering MD040); update the opening triple-backtick for the block that
contains the /gpd:goal, gpd goal status, gpd goal gate, and gpd validate
goal-contract examples to include a language such as bash (e.g., ```bash) so the
block is labeled for markdownlint and docs tooling.</details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro Plus **Run ID**: `d32a669a-b090-4652-a6ef-7d074b58cfa4` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between e96947efa5c3b2e6ce8284227c31e14d9738d0ea and 1e79725d0cb7d33650d0011aef6e92fcc4eaa939. </details> <details> <summary>📒 Files selected for processing (29)</summary> * `CHANGELOG.md` * `CONTRIBUTING.md` * `README.md` * `docs/superpowers/plans/2026-06-04-goal-command.md` * `docs/superpowers/specs/2026-06-04-goal-command-design.md` * `src/gpd/cli.py` * `src/gpd/commands/goal.md` * `src/gpd/core/goal_contract.py` * `src/gpd/core/goal_evidence.py` * `src/gpd/core/goal_gate.py` * `src/gpd/core/state.py` * `src/gpd/registry.py` * `src/gpd/specs/references/help/detailed-command-reference.md` * `src/gpd/specs/templates/state-json-schema.md` * `src/gpd/specs/workflows/goal.md` * `src/gpd/specs/workflows/goal/goal-bootstrap.md` * `src/gpd/specs/workflows/help.md` * `tests/README.md` * `tests/adapters/projection_budget_support.py` * `tests/adapters/test_codex.py` * `tests/adapters/test_runtime_projected_prompt_parity.py` * `tests/adapters/test_runtime_projection_diagnostics_budget.py` * `tests/core/test_cli_goal.py` * `tests/core/test_command_prompt_budget.py` * `tests/core/test_goal_contract.py` * `tests/core/test_goal_evidence.py` * `tests/core/test_goal_gate.py` * `tests/core/test_goal_smoke.py` * `tests/repo_graph_contract.json` </details> <details> <summary>✅ Files skipped from review due to trivial changes (9)</summary> * CHANGELOG.md * src/gpd/specs/workflows/help.md * tests/README.md * src/gpd/specs/references/help/detailed-command-reference.md * tests/core/test_command_prompt_budget.py * src/gpd/specs/workflows/goal.md * README.md * tests/adapters/test_runtime_projection_diagnostics_budget.py * src/gpd/specs/workflows/goal/goal-bootstrap.md </details> <details> <summary>🚧 Files skipped from review as they are similar to previous changes (17)</summary> * tests/repo_graph_contract.json * src/gpd/commands/goal.md * tests/adapters/test_codex.py * tests/adapters/test_runtime_projected_prompt_parity.py * tests/adapters/projection_budget_support.py * src/gpd/registry.py * src/gpd/cli.py * src/gpd/core/state.py * tests/core/test_goal_evidence.py * tests/core/test_goal_smoke.py * src/gpd/specs/templates/state-json-schema.md * src/gpd/core/goal_evidence.py * tests/core/test_cli_goal.py * src/gpd/core/goal_contract.py * tests/core/test_goal_contract.py * tests/core/test_goal_gate.py * src/gpd/core/goal_gate.py </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
- resolve goal gate/status against the project root (mirror gpd state load) - use runtime-aware command text in the missing-contract hint - fail closed on malformed goal_contract during state normalization: drop the whole contract with an integrity finding instead of auto-healing individual fields (a pruned cap could silently weaken gate semantics) - document gpd goal status / gpd goal gate in the README CLI reference - add goal_contract to the JSON-only authority list in state-json-schema.md - markdown polish in goal design/plan docs (Typer, heading levels, fence lang) - ratchet the staged projection char budget for the schema template growth
Summary
Adds
gpd:goal "<statement>" [--budget-usd X] [--max-phases N]: a goal-directed autonomous run that continues itself toward a stated outcome under a binding cap, modeled on the existingautonomousworkflow.goal_contractfield onResearchState): statement, success criteria tied to plan-contract claim ids, USD budget and/or phase-count cap, run status.--max-phasescap binds everywhere. The strictest enforceable cap wins, and a run with no enforceable cap fails closed rather than running uncapped.contract_results.claimsoutcomes written by the verification machinery into phase VERIFICATION.md can mark the goalachieved. The run loop cannot self-declare success. (A non-strict fallback knob exists for demo robustness; failed criteria always block.)gpd goal status(receipt),gpd goal gate(machine decision),gpd validate goal-contract.autonomousworkflow and its stage manifest are untouched;gpd:goalships its ownworkflows/goal/workflow plus a top-levelworkflows/goal.mdcompatibility index.Implemented incrementally via TDD with an adversarial reviewer gating each task.
Design docs
docs/superpowers/specs/2026-06-04-goal-command-design.mddocs/superpowers/plans/2026-06-04-goal-command.mdNotable caveat
The USD-budget receipt only populates on runtimes that record cost telemetry (codex). Under Claude Code the cost ledger stays empty, so the phase-count cap is what binds there — a blocker the spec review caught and the design was reworked around.
Registration & budgets
Adding a new command required registering it across the repo's cross-cutting contracts: skill-category map, command/workflow prompt-budget baselines, runtime-neutral command prefix, same-stem workflow index, and a proportional ratchet of a few runtime-projection advisory ceilings (e.g. the codex per-skill runtime-note aggregate, which grows by one fixed-template note per command). No correctness assertion was weakened; the only
assertvalue changed is an advisory size ceiling.Test status
uv run pytest tests/ -q)test_goal_contract,test_goal_gate,test_goal_evidence,test_cli_goal,test_goal_smoke--checkexit 0)🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
gpd goal status(human receipt),gpd goal gate(JSON decision), andgpd validate goal-contract(validity + issues; non-zero exit on problems).Documentation
Tests