Conversation
…ive check` machine commands
|
Plan Queued for Implementation submission-queuedstatus: queued
queued_at: '2026-03-10T13:29:50.091017+00:00'
submitted_by: schrockn
validation_results:
pr_is_open: true
has_erk_pr_title: true
expected_workflow: plan-implement
trigger_mechanism: label-based-webhook
pr_number: 9162
Plan submitted by schrockn at 2026-03-10T13:29:50.091017+00:00. The Workflow run: https://github.com/dagster-io/erk/actions/runs/22904871122 |
|
⚙️ GitHub Action Started workflow-startedstatus: started
started_at: '2026-03-10T13:30:23Z'
workflow_run_id: '22904871122'
workflow_run_url: https://github.com/dagster-io/erk/actions/runs/22904871122
branch_name: plnd/O9009-objective-json-machi-03-10-1328
pr_number: 9162
Setup completed successfully. Branch: |
erk json objective view and erk json objective check machine commandserk json objective view and erk json objective check machine commands
…ne commands
This PR implements machine-readable JSON commands for objective operations, separating human CLI commands from structured JSON I/O. Both `objective view` and `objective check` are refactored into modular architectures with shared operations, human CLI renderers, and thin machine adapters registered under `erk json objective`.
## Key Changes
- Extract `objective view` into `view/operation.py` (request/result types, `run_objective_view()` function), `view/cli.py` (human command with Rich output), and `view/json_cli.py` (machine adapter)
- Extract `objective check` into `check/validation.py` (pure validation logic), `check/operation.py` (request/result types, `run_objective_check()` function), `check/cli.py` (human command with [PASS]/[FAIL] output), and `check/json_cli.py` (machine adapter)
- Register `json_objective_view` and `json_objective_check` under new `src/erk/cli/commands/json/objective/` group, accessible as `erk json objective view` and `erk json objective check`
- Keep `--json-output` flags on human commands for backwards compatibility during transition (deprecated but functional)
- Update imports across exec scripts and test files to reference new module locations
<details>
<summary>Files Changed</summary>
### Added (13 files)
- `src/erk/cli/commands/objective/view/__init__.py` - View subpackage
- `src/erk/cli/commands/objective/view/operation.py` - Request/result types and operation
- `src/erk/cli/commands/objective/view/cli.py` - Human command with Rich tables
- `src/erk/cli/commands/objective/view/json_cli.py` - Machine adapter
- `src/erk/cli/commands/objective/check/__init__.py` - Check subpackage
- `src/erk/cli/commands/objective/check/validation.py` - Pure validation logic
- `src/erk/cli/commands/objective/check/operation.py` - Request/result types and operation
- `src/erk/cli/commands/objective/check/cli.py` - Human command with [PASS]/[FAIL] output
- `src/erk/cli/commands/objective/check/json_cli.py` - Machine adapter
- `src/erk/cli/commands/json/objective/__init__.py` - JSON objective group
### Modified (8 files)
- `src/erk/cli/commands/json/__init__.py` - Register json_objective_group
- `src/erk/cli/commands/objective/__init__.py` - Update imports to subpackages
- `src/erk/cli/commands/objective/plan_cmd.py` - Import from check/validation
- `src/erk/cli/commands/exec/scripts/objective_plan_setup.py` - Import from check/validation
- `src/erk/cli/commands/exec/scripts/objective_save_to_issue.py` - Import from check/validation
- `tests/unit/cli/commands/objective/test_check_cmd.py` - Import from new locations
- `tests/unit/cli/commands/objective/test_view_cmd.py` - Import from new locations
### Deleted (2 files)
- `src/erk/cli/commands/objective/view_cmd.py` - Migrated to view/ subpackage
- `src/erk/cli/commands/objective/check_cmd.py` - Migrated to check/ subpackage
</details>
## User Experience
**Before:**
```
$ erk objective view 9009
$ erk objective view 9009 --json-output # legacy inline JSON output
```
**After:**
```
$ erk objective view 9009 # unchanged human output
$ erk json objective view # new structured JSON from stdin
$ echo '{"identifier": "9009"}' | erk json objective view
```
Same pattern for `check`: human commands unchanged, new machine commands accessible via `erk json objective check`.
Human commands retain deprecated `--json-output` flags that emit warnings directing users to `erk json objective <view|check>`.
Human CLI output, API contracts, and error handling remain unchanged. This is a pure architectural refactoring to support machine command patterns.
e08ca50 to
91eeb8b
Compare
✅ Test Coverage ReviewLast updated: 2026-03-10 06:48:43 PT No violations detected. All test coverage requirements met. DetailsSource Files Reviewed
Refactoring NotesThis PR restructures objective commands by splitting monolithic files into modular layers:
Existing comprehensive tests cover all three layers:
Files Excluded from Analysis
Activity Log
|
✅ Dignified Python ReviewLast updated: 2026-03-10 06:48:50 PT No violations found. All Python code in PR 9162 adheres to dignified-python standards. DetailsPatterns Checked✅ LBYL over EAFP - Proper control flow patterns with isinstance() checks Files Reviewed
Activity Log
|
✅ Tripwires ReviewLast updated: 2026-03-10 06:49:05 PT No tripwire violations detected. This PR correctly follows the machine command architecture pattern. DetailsTripwires Triggered
Tier 1 Pattern Matches✅ All mechanical pattern checks passed Tier 2 Semantic Matches✅ adding --json flag to human command - Compliant (deprecated in favor of Files Reviewed
Activity Log
|
❌ Dignified Code Simplifier ReviewLast updated: 2026-03-10 06:49:19 PT Found 1 violation across 1 file. Inline comment posted. DetailsPatterns Checked✅ LBYL exception handling - None found Violations Summary
Files Reviewed
Activity Log
|
PR Review Comments AddressedThis PR was reviewed by an automated process triggered by: ResultNo changes were needed to address the review comments. This could mean:
Details
Automated by erk pr-address workflow |
This stack of pull requests is managed by Graphite. Learn more about stacking. |

Refactor objective commands into modular architectures with shared operations, human CLI renderers, and thin machine adapters. Extract
objective viewinto view/operation.py, view/cli.py, and view/json_cli.py with Rich terminal output preserved. Extractobjective checkinto check/validation.py (pure logic), check/operation.py, check/cli.py, and check/json_cli.py with [PASS]/[FAIL] rendering. Register both machine commands under newsrc/erk/cli/commands/json/objective/group, accessible aserk json objective viewanderk json objective check. Human CLI output and API contracts remain unchanged;--json-outputflags kept for backwards compatibility with deprecation warnings.Objective #9009: Objective: Agent-Friendly CLI
Key Changes
erk json objectivegroup--json-outputflags on human commands for backwards compatibility during transitionFiles Changed
Added (13 files)
src/erk/cli/commands/objective/view/__init__.pysrc/erk/cli/commands/objective/view/operation.py- Request/result types and run_objective_view()src/erk/cli/commands/objective/view/cli.py- Human command with Rich outputsrc/erk/cli/commands/objective/view/json_cli.py- Machine adaptersrc/erk/cli/commands/objective/check/__init__.pysrc/erk/cli/commands/objective/check/validation.py- Pure validation logicsrc/erk/cli/commands/objective/check/operation.py- Request/result types and run_objective_check()src/erk/cli/commands/objective/check/cli.py- Human command with [PASS]/[FAIL] outputsrc/erk/cli/commands/objective/check/json_cli.py- Machine adaptersrc/erk/cli/commands/json/objective/__init__.py- JSON objective group registrationModified (8 files)
src/erk/cli/commands/json/__init__.py- Register json_objective_groupsrc/erk/cli/commands/objective/__init__.py- Update imports to subpackagessrc/erk/cli/commands/objective/plan_cmd.py- Import from check/validationsrc/erk/cli/commands/exec/scripts/objective_plan_setup.py- Import from check/validationsrc/erk/cli/commands/exec/scripts/objective_save_to_issue.py- Import from check/validationtests/unit/cli/commands/objective/test_check_cmd.py- Update importstests/unit/cli/commands/objective/test_view_cmd.py- Update importsDeleted (2 files)
src/erk/cli/commands/objective/view_cmd.py- Migrated to view/ subpackagesrc/erk/cli/commands/objective/check_cmd.py- Migrated to check/ subpackageUser Experience
Before:
After:
Same pattern for check: human commands unchanged, machine commands now accessible via
erk json objective check.Human commands retain
--json-outputflags with deprecation warnings pointing users toerk json objective view/check.Human CLI output, error handling, and API contracts remain unchanged. This is a pure architectural refactoring to separate transport concerns from business logic.
original-plan
Plan: Create
erk json objective viewanderk json objective checkmachine commandsPart of Objective #9009, Node 3.2
Context
The "best-of-both-worlds" machine command architecture (PR #9132) separates human CLI commands from machine-readable JSON commands. Human commands live at
erk <path>with rich output; machine commands live aterk json <path>with structured JSON I/O via@machine_command.Currently,
erk objective viewanderk objective checkhave--json-outputflags inline — the legacy pattern. This plan migrates them to the new architecture: extract shared operations intooperation.py, create thinjson_cli.pymachine adapters, and register them undererk json objective view/check.Implementation
Phase 1: Extract
objective viewoperationCreate
src/erk/cli/commands/objective/view/operation.pyExtract from
view_cmd.py:ObjectiveViewRequestfrozen dataclass:identifier: str | None = None(optional, infers from branch)ObjectiveViewResultfrozen dataclass with fields:issue_number,phases(serialized),graph_nodes,unblocked,pending_unblocked,next_node,is_complete,summary. Includeto_json_dict()matching the current_display_jsonoutput shape.run_objective_view()function: the shared logic fromview_objective()that fetches the issue, validates the label, parses the roadmap, builds the graph, and returnsObjectiveViewResult | MachineCommandError.Refactor
view_cmd.py→src/erk/cli/commands/objective/view/cli.pyMove the human command to the new location. It imports from
operation.pyand callsrun_objective_view(), then renders with Rich tables (all existing_format_*and display functions move here).Create
src/erk/cli/commands/objective/view/json_cli.pyThin machine adapter following the pr/view pattern:
No
@mcp_exposedyet — that's node 3.3.Phase 2: Extract
objective checkoperationCreate
src/erk/cli/commands/objective/check/operation.pyExtract from
check_cmd.py:ObjectiveCheckRequestfrozen dataclass:identifier: str(required),allow_legacy: bool = FalseObjectiveCheckResultfrozen dataclass wrappingObjectiveValidationSuccessdata withto_json_dict()matching current_output_jsonshape.run_objective_check(): calls existingvalidate_objective()and wraps the result.Keep
validate_objective(),ObjectiveValidationSuccess,ObjectiveValidationError, and the_check_*helper functions in a shared module (either keep them incheck_cmd.pyand import, or move tocheck/validation.py). Prefer moving tocheck/validation.pysince it's pure logic.Refactor
check_cmd.py→src/erk/cli/commands/objective/check/cli.pyHuman command that calls
run_objective_check()and renders[PASS]/[FAIL]output.Create
src/erk/cli/commands/objective/check/json_cli.pyThin machine adapter:
Phase 3: Register in JSON command tree
Create
src/erk/cli/commands/json/objective/__init__.pyUpdate
src/erk/cli/commands/json/__init__.pyUpdate
src/erk/cli/commands/objective/__init__.pyUpdate imports from new subpackage locations (
view/cli.py,check/cli.py).Phase 4: Deprecate
--json-outputflagsKeep the
--json-outputflags on the human commands for backwards compatibility during transition, but have them emit a deprecation warning pointing toerk json objective view/check. The flags delegate to the samerun_*operation.Key Files
src/erk/cli/commands/objective/view_cmd.pysrc/erk/cli/commands/objective/check_cmd.pysrc/erk/cli/commands/objective/view/__init__.pysrc/erk/cli/commands/objective/view/operation.pysrc/erk/cli/commands/objective/view/cli.pysrc/erk/cli/commands/objective/view/json_cli.pysrc/erk/cli/commands/objective/check/__init__.pysrc/erk/cli/commands/objective/check/validation.pysrc/erk/cli/commands/objective/check/operation.pysrc/erk/cli/commands/objective/check/cli.pysrc/erk/cli/commands/objective/check/json_cli.pysrc/erk/cli/commands/json/objective/__init__.pysrc/erk/cli/commands/json/__init__.pysrc/erk/cli/commands/objective/__init__.pyPatterns to Follow
@machine_command>@click.command>@click.pass_obj(no@mcp_exposed— that's node 3.3)resolve_owner_repo(ctx, target_repo=None)in json_cli.py (same as pr/view/json_cli.py)MachineCommandError(error_type=..., message=...)not exceptionsto_json_dict()on result dataclassesidentifier: str | None = None)@mcp_exposed: That's explicitly node 3.3, not this nodeVerification
erk json objective view --schemareturns valid input/output schemaecho '{"identifier": "9009"}' | erk json objective viewreturns JSON matching currenterk objective view 9009 --json-outputerk json objective check --schemareturns valid schemaecho '{"identifier": "9009"}' | erk json objective checkreturns JSON matching currenterk objective check 9009 --json-outputerk objective view 9009still works (human output unchanged)erk objective check 9009still works (human output unchanged)pytest tests/ -k objectiveplan-header
To replicate this PR locally, run: