M3 — Stage 1: Implement #13

Merged
david merged 1 commit from issue-4/stage-1-implement into main 2026-07-24 20:32:29 +00:00
Owner

Summary

Implements M3 — Stage 1: Implement (#4): turns jira-context.json into an implementation.diff by running a fresh, least-privilege pi agent session inside the target repo, bracketed by a deterministic git preflight and diff capture.

Closes #4.

Changes

  • src/shared/git (new cross-cutting module; reused by Remediate/M5):
    • makeGitRunner — injectable GitRunner over execFile with a large maxBuffer for big diffs.
    • isWorkingTreeClean / assertCleanWorkingTree (throws GitError) / captureBaseRef (git rev-parse HEAD).
    • captureDiffgit diff -- . ':(exclude).pi-loop', enforcing the artifact-exclusion invariant.
  • src/artifacts: writeImplementationDiff / readImplementationDiff / implementationDiffPath (verbatim round-trip).
  • src/implement (new module):
    • buildImplementWrapper() — thin pipeline-contract wrapper (inputs, artifact target, exit condition, no .pi-loop/, no commit).
    • buildImplementUserPrompt(context) — renders JiraContext (handles null/blank acceptance criteria & empty lists).
    • IMPLEMENT_TOOLS allowlist (read, bash, edit, write, grep, find, ls) + DEFAULT_IMPLEMENT_SKILL_BODY.
    • runImplementStage(...) — preflight → compose prompt (skill body + degrade-to-default) → run pi session → capture + persist diff. All external effects are injectable seams.

Testing

  • All tests pass (168 total; 36 new)
  • Full test suite run with no regressions
  • tsc --noEmit, eslint ., prettier --check . clean
  • Manual verification against real git: exclude-pathspec keeps .pi-loop/ out of the diff; preflight reads clean once .pi-loop/ is in .git/info/exclude

Checklist

  • Self-reviewed the diff
  • Code follows project conventions (vertical-slice modules, barrel imports, co-located tests, typed errors)
  • Descriptive naming (no single-character variables)
  • Documentation updated (N/A — schemas unchanged; artifact matches DESIGN §3.3/§3.4)

Notes / scope

  • Wiring runImplementStage into the CLI/end-to-end orchestration is M8, not this milestone.
  • Depends on M1 (Jira context) and M2 (stage harness), both already merged.
## Summary Implements **M3 — Stage 1: Implement** (#4): turns `jira-context.json` into an `implementation.diff` by running a fresh, least-privilege pi agent session inside the target repo, bracketed by a deterministic git preflight and diff capture. Closes #4. ## Changes - **`src/shared/git`** (new cross-cutting module; reused by Remediate/M5): - `makeGitRunner` — injectable `GitRunner` over `execFile` with a large `maxBuffer` for big diffs. - `isWorkingTreeClean` / `assertCleanWorkingTree` (throws `GitError`) / `captureBaseRef` (`git rev-parse HEAD`). - `captureDiff` — `git diff -- . ':(exclude).pi-loop'`, enforcing the artifact-exclusion invariant. - **`src/artifacts`**: `writeImplementationDiff` / `readImplementationDiff` / `implementationDiffPath` (verbatim round-trip). - **`src/implement`** (new module): - `buildImplementWrapper()` — thin pipeline-contract wrapper (inputs, artifact target, exit condition, no `.pi-loop/`, no commit). - `buildImplementUserPrompt(context)` — renders `JiraContext` (handles null/blank acceptance criteria & empty lists). - `IMPLEMENT_TOOLS` allowlist (`read, bash, edit, write, grep, find, ls`) + `DEFAULT_IMPLEMENT_SKILL_BODY`. - `runImplementStage(...)` — preflight → compose prompt (skill body + degrade-to-default) → run pi session → capture + persist diff. All external effects are injectable seams. ## Testing - [x] All tests pass (168 total; 36 new) - [x] Full test suite run with no regressions - [x] `tsc --noEmit`, `eslint .`, `prettier --check .` clean - [x] Manual verification against real git: exclude-pathspec keeps `.pi-loop/` out of the diff; preflight reads clean once `.pi-loop/` is in `.git/info/exclude` ## Checklist - [x] Self-reviewed the diff - [x] Code follows project conventions (vertical-slice modules, barrel imports, co-located tests, typed errors) - [x] Descriptive naming (no single-character variables) - [x] Documentation updated (N/A — schemas unchanged; artifact matches DESIGN §3.3/§3.4) ## Notes / scope - Wiring `runImplementStage` into the CLI/end-to-end orchestration is **M8**, not this milestone. - Depends on M1 (Jira context) and M2 (stage harness), both already merged.
- src/shared/git: injectable GitRunner, clean-tree preflight + base-ref
  capture, and captureDiff using 'git diff -- . :(exclude).pi-loop'.
- src/artifacts: implementation.diff write/read/path helpers.
- src/implement: implement wrapper + user-prompt builders, default skill
  body + least-privilege tool allowlist, and runImplementStage orchestrator
  (preflight → compose prompt → run pi session → capture+write diff, with
  degrade-to-default and injectable seams).

36 new unit tests; tsc/eslint/prettier clean.
david merged commit a38cb7f73e into main 2026-07-24 20:32:29 +00:00
david deleted branch issue-4/stage-1-implement 2026-07-24 20:32:29 +00:00
david referenced this pull request from a commit 2026-07-24 20:32:30 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
david/pi-loop!13
No description provided.