Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions codev/.update-hashes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"protocols/air/builder-prompt.md": "b2acd782a02f1b4426ab50c3628b35340655e9a9b733e667ca655cf171c95931",
"protocols/air/consult-types/impl-review.md": "06001891a3e2df5722b96802f46d2c6563c8006fdfa795d41f9eb629b824d949",
"protocols/air/consult-types/pr-review.md": "e844a116f32fa55667ca331f906a46c70d40c2b55d3ac1fb64dad112a438b371",
"protocols/air/prompts/implement.md": "b891b33a37ff4b1801a62bc93f4a5835c0486bebeed072287905c4c5f7e7adfd",
"protocols/air/prompts/pr.md": "ef459a6bb82e27eb264a12c2f1212baacde0e753196a5e8e6e14c2a95af5cffc",
"protocols/air/protocol.json": "92eec229f4406a27bab90a316c21b14b15b46b530550c4c92e043ce1c2ba8bed",
"protocols/air/protocol.md": "621b7ef44d51a1c45ae1cd2a0531be607c37978e03e4c4c3dcdc0bbcf315efa4",
"protocols/aspir/builder-prompt.md": "ed30dce2c4e3b38a3ecfdf6ffe3ec1faf103cfca7cdc95da29589317db36d699",
"protocols/aspir/consult-types/impl-review.md": "e23d51f2027d0b1492c5db7350dd0cade6d60e9c51617b4a87f8ec9f152e195a",
"protocols/aspir/consult-types/phase-review.md": "e23d51f2027d0b1492c5db7350dd0cade6d60e9c51617b4a87f8ec9f152e195a",
"protocols/aspir/consult-types/plan-review.md": "adaea07d98ad33d257898c291dce3d8fda9d1cab3ccdd7bb47ad6d2d8dfa5137",
"protocols/aspir/consult-types/pr-review.md": "1f63abdf64bf5e915cf5979f7bf772b2701f7ff6eaaebadfe5beebe1bebfec83",
"protocols/aspir/consult-types/spec-review.md": "71b29b32f5d8a99b490edf459aa971b94bfd2c6fa312b5166c2d31b22e7463f2",
"protocols/aspir/prompts/implement.md": "2d5f5d57ed9b45d0e0242046d7db4b914a4d96eab20b1f46d48bb807db0edf5e",
"protocols/aspir/prompts/plan.md": "1a62634a82d0ddca56af1225c3f28635c89ce847c199a85973d1037df2e85b0c",
"protocols/aspir/prompts/review.md": "e67f945ad24e04560a3b0f364c14f8042e91554bf8d086e84fc00acce3df1dca",
"protocols/aspir/prompts/specify.md": "5c6914c126c637785a2c70d02fc69bb4876169b98494492d1a78184cefc87262",
"protocols/aspir/protocol.json": "cb3831d6f0e82f7ab6324e07ea1d12780e51ec56d77950346fc1c4cbd57f7e11",
"protocols/aspir/protocol.md": "2ac5f208e70d2350276d01d0c5e86eb5e443bb9e519ac94bb725fd08c717d752",
"protocols/aspir/templates/plan.md": "590748f5a8d2e75e996fa55b3ac2594a0320f7a8783d218c64e0f1265a70c54f",
"protocols/aspir/templates/review.md": "47183b106acd750f9e7e33bc03d0821e60ad7b0543c404b3e484ebe1c4b26cc0",
"protocols/aspir/templates/spec.md": "5d285bf27a090667b38031fa7fdd3d50c6912f522fe6b0c98fe464024dc1be2d",
"protocols/bugfix/builder-prompt.md": "554ff2b3f7e278f78e73c924c3925c31eeb913f404743b94836a1955501e5cff",
"protocols/bugfix/consult-types/impl-review.md": "e23d51f2027d0b1492c5db7350dd0cade6d60e9c51617b4a87f8ec9f152e195a",
"protocols/bugfix/consult-types/pr-review.md": "1f63abdf64bf5e915cf5979f7bf772b2701f7ff6eaaebadfe5beebe1bebfec83",
"protocols/bugfix/prompts/fix.md": "8f064391a0fecf1a9993d575cf958074e17f5a002110e669262d86bf6480b3ea",
"protocols/bugfix/prompts/investigate.md": "ea4a357896e681dd7331752bfb92e3f1430b43b6ed805d26c5832ea2d4f511ef",
"protocols/bugfix/prompts/pr.md": "eccfa486ccf8d2bd5aa47ff32684512ce19ccb22e94c269a536b09939bc87bcd",
"protocols/bugfix/protocol.json": "c7306fde4c84688675a340227435812fd2d0a6fc8a6797b8b61cb03426e52db9",
"protocols/experiment/builder-prompt.md": "f2e0dd7b5ab59dc9e6b14aee2188661a4e59c8fc5f4fee633bbe1282d7efd2c1",
"protocols/experiment/protocol.json": "93f4461dee32f1427f8d0343675e78be10f393ff91fffa818fa9df591316f4dc",
"protocols/experiment/protocol.md": "0b16e4567c7128568f78fd270657755daf90cd6e4869dc3360364aa84e1d1521",
"protocols/experiment/templates/notes.md": "d7b49794a07db3c8175c29c9baf76973416f2a9d9ec133c7429fc37a067dd0d6",
"protocols/maintain/builder-prompt.md": "85b33d21d1522373efe41081c7e76d66f6ddf01f95f24d36c4cfeae0ae6e65ec",
"protocols/maintain/consult-types/impl-review.md": "e23d51f2027d0b1492c5db7350dd0cade6d60e9c51617b4a87f8ec9f152e195a",
"protocols/maintain/consult-types/pr-review.md": "1f63abdf64bf5e915cf5979f7bf772b2701f7ff6eaaebadfe5beebe1bebfec83",
"protocols/maintain/prompts/audit.md": "5a7ffea829dbc27a3f433de12fbd1c5b7902a8a945bf17868aea732aa75f0c8b",
"protocols/maintain/prompts/clean.md": "30061cf0eb7bec533e893f3148b6563e6b7b4c38f9dbd93c1be72542aa047059",
"protocols/maintain/prompts/sync.md": "3ddfbd5e1d5ae9b89cf5d91968b2353d76a5f743b6d7b8a66f3a54632e0d7f8a",
"protocols/maintain/prompts/verify.md": "1fb8b8ba3a1772d2d07d843f5c601bfef60d007aa72108cc6e83f8524e62df4d",
"protocols/maintain/protocol.json": "4bb736b1f2f295166dd9a58a973cd5dec6b76b3b2ca490b54f946c0d0efbf096",
"protocols/maintain/protocol.md": "09dbc868eca24a5e4f5705ead72f5d20937c714b8c9101f5710d3240bd5cabc5",
"protocols/maintain/templates/maintenance-run.md": "6bbd4a11f946a610e5bcccf0ca90e6064ec1776eedccb07bc6885a334a76ac08",
"protocols/protocol-schema.json": "02cd6945c385443e0c6673cc64a052804eed597e22301a5779c54c6755de1eda",
"protocols/spike/builder-prompt.md": "a389f269b8eb53b4f978e55c819e05165c3f343a5bccba868bcd3d4334e911a5",
"protocols/spike/protocol.json": "f6948f3e5159fbabbe2cfc869a9d910f9e20b4638c3828225f065f5ee36cc858",
"protocols/spike/protocol.md": "d24848da55501e06d7e737e8e2da87b7d0f43d4ee326c3e8f175e2357d937362",
"protocols/spike/templates/findings.md": "ce2d0c2586eefbab8738ae7844f0e75e2aa2aec0dea78e32932867b2240aa867",
"protocols/spir/builder-prompt.md": "ed30dce2c4e3b38a3ecfdf6ffe3ec1faf103cfca7cdc95da29589317db36d699",
"protocols/spir/consult-types/impl-review.md": "e23d51f2027d0b1492c5db7350dd0cade6d60e9c51617b4a87f8ec9f152e195a",
"protocols/spir/consult-types/phase-review.md": "e23d51f2027d0b1492c5db7350dd0cade6d60e9c51617b4a87f8ec9f152e195a",
"protocols/spir/consult-types/plan-review.md": "adaea07d98ad33d257898c291dce3d8fda9d1cab3ccdd7bb47ad6d2d8dfa5137",
"protocols/spir/consult-types/pr-review.md": "1f63abdf64bf5e915cf5979f7bf772b2701f7ff6eaaebadfe5beebe1bebfec83",
"protocols/spir/consult-types/spec-review.md": "71b29b32f5d8a99b490edf459aa971b94bfd2c6fa312b5166c2d31b22e7463f2",
"protocols/spir/prompts/implement.md": "2d5f5d57ed9b45d0e0242046d7db4b914a4d96eab20b1f46d48bb807db0edf5e",
"protocols/spir/prompts/plan.md": "1a62634a82d0ddca56af1225c3f28635c89ce847c199a85973d1037df2e85b0c",
"protocols/spir/prompts/review.md": "e67f945ad24e04560a3b0f364c14f8042e91554bf8d086e84fc00acce3df1dca",
"protocols/spir/prompts/specify.md": "5c6914c126c637785a2c70d02fc69bb4876169b98494492d1a78184cefc87262",
"protocols/spir/protocol.json": "61193d795dad74af0b42452df1607fbc6fc1ea81a9af2cc968b4440320c70d0c",
"protocols/spir/protocol.md": "f9297b94ff2a296f45329a72c1f8bc08d817ec5b7055392ff0120bd9191788e5",
"protocols/spir/templates/plan.md": "590748f5a8d2e75e996fa55b3ac2594a0320f7a8783d218c64e0f1265a70c54f",
"protocols/spir/templates/review.md": "47183b106acd750f9e7e33bc03d0821e60ad7b0543c404b3e484ebe1c4b26cc0",
"protocols/spir/templates/spec.md": "5d285bf27a090667b38031fa7fdd3d50c6912f522fe6b0c98fe464024dc1be2d",
"protocols/tick/builder-prompt.md": "bb4d5eab37b786cf8db9f91698d11486ca4f595950bf9b93cbd20000202e9e13",
"protocols/tick/consult-types/impl-review.md": "e23d51f2027d0b1492c5db7350dd0cade6d60e9c51617b4a87f8ec9f152e195a",
"protocols/tick/consult-types/plan-review.md": "adaea07d98ad33d257898c291dce3d8fda9d1cab3ccdd7bb47ad6d2d8dfa5137",
"protocols/tick/consult-types/pr-review.md": "1f63abdf64bf5e915cf5979f7bf772b2701f7ff6eaaebadfe5beebe1bebfec83",
"protocols/tick/consult-types/spec-review.md": "71b29b32f5d8a99b490edf459aa971b94bfd2c6fa312b5166c2d31b22e7463f2",
"protocols/tick/protocol.json": "e124dba1fb2918868c34c5bd5475857f7be1e7bf0d2fef2f133ad85dd37428a1",
"protocols/tick/protocol.md": "412cd5e9600e988ebe5a4338c902bbb8c43b3322ea2cc7e54054f0fea2f534bc",
"protocols/tick/templates/plan.md": "74a8810b696b49b8c38bbaa75ceb35ff33494feb6cab6058a873c5406ef0987c",
"protocols/tick/templates/review.md": "9a19816fef965a22e88f29935dd3c0ae5f21a9d603820bfbd08b4ea25f0fc2c1",
"protocols/tick/templates/spec.md": "6dc83459a4ee6973e25be638303e3bfcce54556661577d18884913c86ddc4021",
"resources/commands/agent-farm.md": "e31be4eddfcdbe7a33dd383fd7d76397c3950a63be829facb0d8d69e12141b23",
"resources/commands/codev.md": "4199872530cfe6d2d7b99f2c82239f35167fbc36c2c2e0f30827277466688546",
"resources/commands/consult.md": "5c19efc3d6cff82ee0973b1850645d9f057d7bad601848917325abf6f41aba61",
"resources/commands/overview.md": "4847485250a4b17e963a1fee38d93f44bc79a3cd09f1fe07937959ac4bf1000b",
"resources/workflow-reference.md": "5dda6d73f7dfcdb6daa779ccd14c3fda2e6f5bd6678c00bd9adbe4baf30f2ff1",
"templates/AGENTS.md": "47b2371af786292e7f581d78741f0065af43a4c7e8995df1573dbe6b3a89e82d",
"templates/CLAUDE.md": "af0cdfffab08f15d3d27e09a9a44bde2ce4a334f45c38e6ee04dd699f6b6336e",
"templates/arch.md": "6a265de043e003c422532514cddc148a36d928937664ffa66c61f728b20797a5",
"templates/cheatsheet.md": "b92846ad5fc2e4adcd610c96e6281ccc95ae1a7ecf5074aaa5f764a8ee5128a9",
"templates/lessons-learned.md": "b79fbacd47d76ebe393909990eb38d5583e8e928e8218bbcf01cf2882105cac5",
"templates/lifecycle.md": "b4f4ad8dfc40c25a5c33f5797e5958cfce2510bc8d3d7a43b86e825ee5351a6a",
"templates/pr-overview.md": "9884057783064910503dfa8c697142c6d241cce2b7aa860ded5822c46530691f"
}
75 changes: 75 additions & 0 deletions codev/consult-types/integration-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Integration Review Prompt

## Context
You are performing an integration review of a pull request. The builder has created a PR and you are evaluating whether this change fits well into the broader system. This is the architect's review, focusing on how the change integrates rather than whether it works.

## Focus Areas

1. **Architectural Fit**
- Does this change follow existing patterns in the codebase?
- Are there inconsistencies with how similar things are done elsewhere?
- Does it introduce new patterns that should be adopted more broadly?
- Are dependencies appropriate and minimal?

2. **System Impact**
- What other parts of the system might be affected?
- Are there potential side effects not addressed?
- Does this break any existing functionality?
- Are there performance implications?

3. **API/Interface Quality**
- Are new interfaces well-designed and consistent?
- Will this be easy for other developers to use?
- Is it properly documented for consumers?
- Does it follow existing conventions?

4. **Maintenance Burden**
- Is this code maintainable by others?
- Are there any "clever" solutions that should be simplified?
- Is the complexity justified?
- Will this be easy to debug when issues arise?

5. **Migration/Compatibility**
- Are there backward compatibility concerns?
- Is migration path clear for existing users?
- Are breaking changes properly communicated?

6. **UX Verification** (if spec has UX requirements)
- Does the actual user experience match what the spec describes?
- Compare spec's "Goals" section and flow diagrams to actual behavior
- If spec says "async/non-blocking", verify the code is actually async
- If spec says "immediate response", verify user isn't blocked waiting
- **CRITICAL:** Tests passing does NOT mean UX requirements are met - verify manually

## Verdict Format

After your review, provide your verdict in exactly this format:

```
---
VERDICT: [APPROVE | REQUEST_CHANGES | COMMENT]
SUMMARY: [One-line summary of your assessment]
CONFIDENCE: [HIGH | MEDIUM | LOW]
---
KEY_ISSUES:
- [Issue 1 or "None"]
- [Issue 2]
...

INTEGRATION_NOTES:
- [Note about system integration]
- [Note about follow-up work needed]
```

**Verdict meanings:**
- `APPROVE`: Ready to merge
- `REQUEST_CHANGES`: Integration issues that must be addressed
- `COMMENT`: Suggestions for improvement, can merge but consider feedback

## Notes

- The implementation has already been reviewed - don't re-review code quality
- Focus on "how does this fit the system" not "does this work"
- Consider: Will I regret merging this in 6 months?
- If requesting changes, be specific about what needs to change
- INTEGRATION_NOTES can include suggestions for follow-up specs
99 changes: 99 additions & 0 deletions codev/plans/14-tick-001-jj-auto-install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Plan: TICK 14-001 — JJ Auto-Install CLI Command

## Phase 1: `install-jj` subcommand

### Files to create/modify

**`src/fava_trails/cli.py`** — Add `cmd_install_jj` function and wire up subparser:

```python
def cmd_install_jj(args: argparse.Namespace) -> int:
"""Download and install the JJ binary."""
```

Logic:
1. Check if JJ already installed:
- Parse installed version from `jj version` output
- If installed version == target version → print version, exit 0
- If versions differ → proceed with install (upgrade/downgrade)
2. Detect platform: `sys.platform` + `platform.machine()`
3. Map to release artifact name:
- `linux` + `x86_64` → `x86_64-unknown-linux-musl`
- `linux` + `aarch64` → `aarch64-unknown-linux-musl`
- `darwin` + `x86_64` → `x86_64-apple-darwin`
- `darwin` + `arm64` → `aarch64-apple-darwin`
- `win32` → print `winget install Jujutsu.Jujutsu` and exit 1
- else → error with manual install URL
4. Download tarball from `https://github.com/jj-vcs/jj/releases/download/v{VERSION}/jj-v{VERSION}-{suffix}.tar.gz`
5. Extract to tempdir, copy `jj` binary to `~/.local/bin/jj`
6. `chmod +x`
7. Verify: run `jj version`, print output
8. Post-install PATH check: run `shutil.which("jj")` — if None, print clear warning with instructions to add `~/.local/bin` to PATH

Constants: `JJ_VERSION = "0.28.0"` (match `scripts/install-jj.sh`), `INSTALL_DIR = ~/.local/bin`

Dependencies: `urllib.request`, `tarfile`, `tempfile`, `shutil`, `platform` — all stdlib.

### Subparser registration

```python
p_install_jj = subparsers.add_parser("install-jj", help="Download and install the Jujutsu (JJ) binary")
p_install_jj.add_argument("--version", default=None, help="JJ version to install (default: 0.28.0)")
p_install_jj.set_defaults(func=cmd_install_jj)
```

### Done criteria
- `fava-trails install-jj` downloads and installs JJ on Linux x86_64
- Skips if already installed
- `--version` flag allows pinning

## Phase 2: Error message cleanup

### Files to modify

1. **`src/fava_trails/cli.py:212`** (`cmd_bootstrap`):
```
- "Error: jj not found. Install with: bash scripts/install-jj.sh"
+ "Error: jj not found. Install with: fava-trails install-jj\n Or manually: https://jj-vcs.github.io/jj/"
```

2. **`src/fava_trails/cli.py:427`** (`cmd_doctor`):
```
- " Fix: bash scripts/install-jj.sh"
+ " Fix: fava-trails install-jj"
```

3. **`src/fava_trails/vcs/jj_backend.py:64-65`** (`_find_jj`):
```
- "jj binary not found. Install from https://jj-vcs.github.io/jj/ or run scripts/install-jj.sh (from source repo)"
+ "jj binary not found. Install with: fava-trails install-jj (or manually from https://jj-vcs.github.io/jj/)"
```

4. **`tests/conftest.py:14`**:
```
- "jj binary not found — install via scripts/install-jj.sh"
+ "jj binary not found — install via: fava-trails install-jj"
```

### Done criteria
- Zero references to `scripts/install-jj.sh` in Python source files
- All JJ-missing errors point to `fava-trails install-jj`

## Phase 3: Tests

### New tests in `tests/test_cli.py`

1. `test_install_jj_skips_if_present` — mock `shutil.which` returning jj → exit 0, prints version
2. `test_install_jj_unsupported_platform` — mock `sys.platform` to `"win32"` → exit 1, prints manual URL
3. `test_install_jj_downloads_and_installs` — mock `urllib.request.urlopen`, verify binary placed in expected path
4. `test_install_jj_custom_version` — verify `--version 0.29.0` changes download URL

### Existing test updates

- `test_bootstrap_fails_if_jj_missing` — assert new error message text
- `test_cli.py:477` — assert `install-jj` in output (not `install-jj.sh`)
- `test_doctor_jj_missing` — assert new fix message

### Done criteria
- All new tests pass
- All existing tests pass (181 total)
69 changes: 69 additions & 0 deletions codev/protocols/air/builder-prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# {{protocol_name}} Builder ({{mode}} mode)

You are implementing {{input_description}}.

{{#if mode_soft}}
## Mode: SOFT
You are running in SOFT mode. This means:
- You follow the AIR protocol yourself (no porch orchestration)
- The architect monitors your work and verifies you're adhering to the protocol
- Consultation is optional — use your judgement based on complexity
- You have flexibility in execution, but must stay compliant with the protocol
{{/if}}

{{#if mode_strict}}
## Mode: STRICT
You are running in STRICT mode. This means:
- Porch orchestrates your work
- Run: `porch next` to get your next tasks
- Follow porch signals and gate approvals

### ABSOLUTE RESTRICTIONS (STRICT MODE)
- **NEVER edit `status.yaml` directly** — only porch commands may modify project state
- **NEVER call `porch approve` without explicit human approval** — only run it after the architect says to
{{/if}}

## Protocol
Follow the AIR protocol: `codev/protocols/air/protocol.md`

{{#if issue}}
## Issue #{{issue.number}}
**Title**: {{issue.title}}

**Description**:
{{issue.body}}

## Your Mission
1. Read the issue requirements carefully
2. Implement the feature (< 300 LOC)
3. Write tests for the feature
4. Create PR with review in the PR body (NOT as a separate file)
5. Notify architect via `af send architect "PR #N ready for review (implements #{{issue.number}})"`

**IMPORTANT**: AIR produces NO spec, plan, or review files. The review goes in the PR body.

If the feature is too complex (> 300 LOC or architectural changes), notify the Architect via:
```bash
af send architect "Issue #{{issue.number}} is more complex than expected. [Reason]. Recommend escalating to ASPIR."
```

## Notifications
Always use `af send architect "..."` to notify the architect at key moments:
- **PR ready**: `af send architect "PR #N ready for review (implements #{{issue.number}})"`
- **PR merged**: `af send architect "PR #N merged for issue #{{issue.number}}. Ready for cleanup."`
- **Blocked**: `af send architect "Blocked on issue #{{issue.number}}: [reason]"`
{{/if}}

## Handling Flaky Tests

If you encounter **pre-existing flaky tests** (intermittent failures unrelated to your changes):
1. **DO NOT** edit `status.yaml` to bypass checks
2. **DO NOT** skip porch checks or use any workaround to avoid the failure
3. **DO** mark the test as skipped with a clear annotation (e.g., `it.skip('...') // FLAKY: skipped pending investigation`)
4. **DO** document each skipped flaky test in the PR body under a "Flaky Tests" section
5. Commit the skip and continue with your work

## Getting Started
1. Read the AIR protocol
2. Review the issue details
3. Implement the feature
Loading
Loading