Dev PR¶
Commit work-buddy code changes with test verification, chained doc update, PII scan, cleanup review, and commit metadata recording. Replaces the prose /wb-commit directions.
Workflow name: dev-pr
Execution: main
Slash command: /wb-dev-pr
Override not allowed
Steps¶
| # | ID | Name | Type | Depends on |
|---|---|---|---|---|
| 1 | assess |
Snapshot git state (branch, changed files, test candidates) | code |
|
| 2 | branch_guard |
Confirm branch (or create one off main) | reasoning |
assess |
| 3 | test |
Run relevant tests; record pass/fail | reasoning |
branch_guard |
| 4 | document |
Update knowledge-store docs via /wb-dev-document (or explicitly skip with rationale) | reasoning |
test |
| 5 | pii_check |
Scan changed files for PII patterns | code |
document |
| 6 | cleanup |
Review own changes for debug code, stale refs, PII hits | reasoning |
pii_check |
| 7 | commit |
Stage precisely and commit | reasoning |
cleanup |
| 8 | record |
Record structured commit metadata via commit_record | code |
commit |
| 9 | push |
Ask user about push + PR; act on the answer | reasoning |
record |
Step instructions¶
assess¶
Auto-run. The conductor calls work_buddy.dev.commit.assess_state() and passes the result forward. Returned fields:
- current_branch, is_main: branch info.
- changed_files, classified: what you're about to commit, by bucket (module / knowledge / slash / tests / config / other).
- test_candidates: test files that might apply, heuristically derived from changed module names.
- warnings: soft signals (on main, direct JSON edits, empty diff).
branch_guard¶
Reasoning step. Read assess.is_main. If true, tell the user they're on a protected branch and create a new one:
git checkout -b <branch-name>
Naming:
- fix/<short> — bug fixes
- feat/<short> — new features or capabilities
- docs/<short> — documentation-only
- chore/<short> — config / CI / deps
If on a feature branch already, confirm the name matches the work and proceed.
Advance with {"branch": "<current branch name>", "ready": true}. Set ready: false only if the user explicitly aborted.
Advance via wb_advance(workflow_run_id=..., step_result={...}). The parameter is step_result (not result) — FastMCP silently drops unknown kwargs.
test¶
Reasoning step. For each module file you changed (assess.classified.module), run its matching test file(s). The conductor suggested candidates in assess.test_candidates — check them first, but also look for test files that import the modules you changed if the heuristic missed them.
Run via:
export WORK_BUDDY_SESSION_ID='test-session-00000000' && \
python -m pytest <test_files> -q --tb=short
Record: which files ran, pass count, fail count. If any failure is on code you changed, advance with blocking: true and fix before retrying the step. If failures are on code you didn't touch, note them and advance with blocking: false.
If no test files apply (e.g. pure doc change), advance with tests_run: [], tests_passed: 0, tests_failed: 0, blocking: false.
Advance shape:
{
"tests_run": ["tests/unit/test_foo.py"],
"tests_passed": 12,
"tests_failed": 0,
"blocking": false,
"rationale": "optional — e.g. 'no tests apply for pure doc change'"
}
Advance via wb_advance(workflow_run_id=..., step_result={...}). The parameter is step_result (not result) — FastMCP silently drops unknown kwargs.
document¶
Reasoning step with a sub-workflow reference. The parent workflow expects you to run /wb-dev-document (workflow name dev-document) to propagate your code changes into the knowledge store before committing.
The normal path¶
`mcp__work-buddy__wb_run("dev-document")`
Run the sub-workflow to completion (scan → propose → confirm → apply → validate → report). Then advance this step with:
{
"skipped": false,
"doc_result": { /* the dev-document apply step's result */ },
"units_updated": ["<unit path>", ...]
}
If dev-document's validate step reports failures, resolve them before advancing this step — don't commit with a broken store.
The escape hatch (use sparingly)¶
If the commit is genuinely trivial — a typo, formatting, a test-only change that documents nothing observable — you may skip. skip_rationale is required and must be specific; 'trivial' alone is not acceptable:
{
"skipped": true,
"skip_rationale": "Typo fix in a docstring; no behavior change."
}
The rationale will be included in the commit body at the record step so the skip is auditable. If you find yourself writing a long rationale, that's a signal the change is not trivial — run dev-document instead.
Advance via wb_advance(workflow_run_id=..., step_result={...}). The parameter is step_result (not result) — FastMCP silently drops unknown kwargs.
pii_check¶
Auto-run. The conductor calls work_buddy.dev.commit.pii_check() against the current change set. Returns {files_scanned, hits, clean}.
- clean: true → proceed.
- hits → each entry has file, line, label, match, context. Fix before committing. Common fixes: replace personal paths with config-driven values (cfg["vault_root"]), replace named references to the user with 'the user', move machine-specific paths to gitignored configs.
cleanup¶
Reasoning step. Walk each file you changed and look for:
- Debug prints, TODO/FIXME you left while working.
- Stale imports or references to things you renamed.
- Dead code from a refactor.
- PII hits from the previous step — if any, fix them now.
- Transient narrative in durable surfaces. Scan changed code (identifiers, comments, log strings, tests) and agent docs (knowledge units, slash-command text, CLAUDE.md) for references whose meaning depends on the moment the change was made: branch names, PR numbers, dates, agent-session tags, "after the recent migration", "Slice 3"-style stage labels, "for now", "temporary workaround", or identifiers that read as archaeology (legacy_*, _after_migration_shim, pre_2026_04_26_*). Replace with stable domain terms describing current behavior. Versioned labels are allowed only when they name a documented interface, schema, protocol, migration, or compatibility boundary; otherwise rename. Commit messages are exempt — they're a write-once journal of how the change arrived.
Do not refactor unrelated code. Scope is your own changes only.
Advance with {"ready": true} when clean. If you find and fix issues, mention them in your response so the user sees the pass happened.
Advance via wb_advance(workflow_run_id=..., step_result={...}). The parameter is step_result (not result) — FastMCP silently drops unknown kwargs.
commit¶
Reasoning step. Stage and commit.
Sign off every commit (DCO)¶
work-buddy enforces a Developer Certificate of Origin: every commit must be signed off with the -s flag (git commit -s ...), which appends a Signed-off-by trailer. The DCO status check is required on main — a pull request with any unsigned commit cannot merge. Commit with -s from the start; to repair commits already made without it, run git rebase --signoff origin/main and force-push.
Stage precisely¶
Do NOT use git add -A or git add ..
- When you own the whole file's diff:
git add <file1> <file2>. - When a file mixes your hunks with another agent's:
git add -p <file>and accept only yours.
Verify with git diff --cached --stat that only your intended changes are staged.
Commit message¶
Follow the repo's conventional-commit style (check git log --oneline -5). Keep the subject short and imperative; put the why in the body.
If the document step was skipped, paste the skip_rationale into the commit body under a Doc-update skipped: line so the skip is visible in history.
Use a HEREDOC for multi-line commit messages, and keep the -s:
git commit -s -m "$(cat <<'EOF'
<subject>
<body>
EOF
)"
Advance with:
{
"commit_hash": "<full or 7+ char hash from git output>",
"message": "<subject line>",
"staged_files": ["..."]
}
Advance via wb_advance(workflow_run_id=..., step_result={...}). The parameter is step_result (not result) — FastMCP silently drops unknown kwargs.
record¶
Code step. Dispatch commit_record via wb_run with structured metadata. Pull most fields from prior step_results:
`mcp__work-buddy__wb_run("commit_record", {
"commit_hash": <commit.commit_hash>,
"message": <commit.message>,
"branch": <branch_guard.branch>,
"files_changed": ",".join(<commit.staged_files>)`,
"tests_run": ",".join(<test.tests_run>),
"tests_passed": <test.tests_passed>,
"tests_failed": <test.tests_failed>,
"knowledge_units_updated": ",".join(<document.units_updated or []>),
"summary": <one-line plain-English summary>,
})
Return the result dict unchanged. If commit_record fails, surface the error and proceed to the push step — a failed metadata record does not block the commit from being pushed.
Advance via wb_advance(workflow_run_id=..., step_result={...}). The parameter is step_result (not result) — FastMCP silently drops unknown kwargs.
push¶
Reasoning step. Ask the user: "Want me to push and create a PR?"
If yes:
git push -u origin <branch>
gh pr create --title "<concise title>" --body "$(cat <<'EOF'
## Summary
<1-3 bullets>
## Test plan
- [ ] <what to verify>
Task: <task-id if any>
EOF
)"
Report the PR URL back.
If the user declines, confirm the commit is on the local branch and remind them they can push later. Do NOT push without asking — this is a shared-state action that requires explicit consent.
Advance via wb_advance(workflow_run_id=..., step_result={...}). The parameter is step_result (not result) — FastMCP silently drops unknown kwargs.
Context¶
Commit work-buddy code with test verification, doc hygiene (via chained /wb-dev-document), PII scan, cleanup review, structured commit metadata recording, and optional push + PR.
Philosophy¶
The previous /wb-commit was a prose checklist loaded by a slash command. Agents skipped the doc-update step under time pressure and silently left stale knowledge units in place. This workflow makes the doc check a DAG step whose skip requires explicit rationale, recorded in the commit body — so skipping is auditable, not invisible.
What this workflow is NOT¶
- Not a general code-review step. Use
/security-reviewor a PR reviewer for deeper passes. - Not a substitute for the agent's judgment on what 'precise staging' means. You still need to read your own diffs.
- Not a gate on operational work. Only use from dev mode (after
/wb-devorient) when changing the work-buddy codebase itself.
Doc-update skip policy¶
document.skipped: true is allowed but expensive: the skip rationale lands in the commit body, visible forever. Use only when the change genuinely documents nothing observable (pure typos, whitespace, test-only internals). When in doubt, run dev-document — empty proposals: [] is cheap and honest.