Phase 3: Agent Label Behavior (Profiles + Hooks + Skill Updates)
Goal: Agents automatically signal workflow state via Forgejo labels at every stage transition. Enforced by hooks — not dependent on agent memory.
Owner: Betty Sue (Claude config development per
sop-claude-config-development)Repo:
forgejo_admin/claude-custom (symlinked as ~/.claude/)Forgejo Issue: TBD
Architecture: Three Enforcement Layers
| Layer | What | Enforcement |
|---|---|---|
| <strong>Hooks</strong> (PostToolUse) | Set labels + comment on issue automatically when tools fire | Strong — can't be skipped, fires regardless of agent prompt |
| <strong>Skills</strong> (/review-pr) | Structured workflow with parseable verdict output | Medium — agent follows recipe, hook parses output |
| <strong>Profiles</strong> (dev.md, qa.md) | Mention labels so agents understand workflow context | Weak — awareness only, not enforcement |
Key insight: Hooks are the enforcement layer, not prompts. The
forgejo-helper.sh already has curl patterns + credential loading. PostToolUse hooks run as shell scripts with full API access regardless of agent permissions. Agents don't need set_label MCP tools — the hooks handle it.MCP Gap (discovered scope)
The forgejo-mcp server has NO
set_label or comment_on_issue tools. This is why hooks are the right approach for now — they bypass the gap. A TODO for forgejo-mcp should be created to add these tools properly.Hook Implementations
1. PostToolUse on
mcp__forgejo__create_issue_and_branch:- Extract owner, repo, issue number from tool input
- curl: set
status:in-progresslabel on the issue - Inject context: "Label status:in-progress set on issue #N"
2. PostToolUse on
mcp__forgejo__submit_pr:- Extract owner, repo from tool input; extract issue number from branch name or PR body
- curl: set
status:qalabel on the parent issue (replace any existing status label) - curl: comment on the issue with PR URL ("PR #N submitted: [url]")
- Inject context: "Label status:qa set + PR linked on issue #N"
- Extends existing
remind-mcp-review-loop.sh— or chains after it
3. PostToolUse on
mcp__forgejo__comment_on_pr:- Parse the comment body for verdict: look for "VERDICT: APPROVED" or "VERDICT: NOT APPROVED"
- If APPROVED: curl set
status:approvedlabel on parent issue, curl comment approval summary on issue - If NOT APPROVED: curl set
status:needs-fixlabel on parent issue, curl comment required fixes on issue - If no verdict found: no-op (not all PR comments are review verdicts)
Skill Update: /review-pr
- Update
skill-review-prnote to require VERDICT line in exact format:### VERDICT: APPROVEDor### VERDICT: NOT APPROVED - This makes the verdict parseable by the PostToolUse hook
- QA continues to comment on PRs (existing capability); hook mirrors findings to the issue
Profile Updates: dev.md + qa.md
- Add awareness section: "Hooks automatically set Forgejo labels when you use MCP tools"
- Dev: mention that
status:in-progressandstatus:qaare set by hooks after create_issue_and_branch and submit_pr - QA: mention that
status:approved/status:needs-fixis set by hook based on VERDICT line in PR comment - These are informational — the hooks enforce regardless
Helper Function Additions: forgejo-helper.sh
forgejo_set_label()— set a label on an issue (replace existing status: labels)forgejo_comment_on_issue()— comment on an issue (not a PR)forgejo_get_issue_number_from_branch()— extract issue # from branch name pattern
Steps
- Add helper functions to
forgejo-helper.sh - Create
label-on-branch.sh— PostToolUse hook for create_issue_and_branch - Create
label-on-pr.sh— PostToolUse hook for submit_pr (chains with existing remind-mcp-review-loop.sh) - Create
label-on-verdict.sh— PostToolUse hook for comment_on_pr - Register hooks in
settings.json - Update
skill-review-prnote — require parseable VERDICT format - Update
dev.mdandqa.md— awareness of label hooks - Test: spawn dev agent on a real issue, verify labels set automatically
- Test: spawn QA agent, verify verdict parses and label sets
Deliverable: Every submit_pr automatically sets status:qa. Every QA verdict automatically sets status:approved or status:needs-fix. Every branch creation sets status:in-progress. All enforced by hooks — zero agent memory required.
Depends on: Phase 1 (labels exist on repos) — COMPLETED. Phase 2 (SOPs document the protocol) — COMPLETED.