Skip to content

pr-ready workflow blocked by guard: prompt+hard enforcement contradicts step bodies #78

Description

@5uck1ess

Summary

workflows/pr-ready.yml cannot complete end-to-end because the devkit-guard blocks 7 of its 9 steps from running the tools their step bodies explicitly require. Hit during PR #77's own `/devkit:pr-ready` run — had to finish the PR manually outside the workflow.

Root cause

pr-ready.yml has no top-level enforce: field, so it defaults to hard via validate() in src/engine/workflow.go:88-90. Combined with stepType() in src/mcp/tools.go:260-268 classifying every prompt:-only step as "prompt", this means every pr-ready step hits the prompt + hard branch of the guard in src/cmd/guard.go:349-364 — which blocks everything except Read, Grep, Glob, TodoWrite, NotebookRead, Skill, and devkit MCP tools.

guard_test.go:257 asserts prompt+hard+Bash → block is intentional (comment: "(issue #63 drift hole)"), so this is enforcement working as designed against a workflow that wasn't written to that contract.

Structural contradiction

Step Body says Tool needed Under prompt+hard
validate Run git commands Bash ❌ blocked
necessity Remove debug artifacts Edit ❌ blocked
lint Run linter, fix violations Bash + Edit ❌ blocked
test Run tests, fix failures Bash + Edit ❌ blocked
security Review (read-only) Read/Grep ✅ OK
doc-check "apply the edit directly" Edit ❌ blocked
changelog Generate text (none) ✅ OK
create-pr `git push` + `gh pr create` Bash ❌ blocked
monitor `gh pr checks` + `git push` Bash ❌ blocked

Quick fix (one line)

Add `enforce: soft` at the top of `workflows/pr-ready.yml`, matching `tri-review.yml` and `tri-security.yml`:

```yaml
name: PR Ready
description: Full PR preparation pipeline — ...
enforce: soft # <- add this
```

Soft enforcement still routes through the guard (stderr nudge, Stop-hook still blocks session end until all steps complete) — it just doesn't hard-block tool calls the step needs.

Other likely-affected workflows

Audit candidates (workflows with `prompt:` steps that run shell/edit files, no explicit `enforce: soft`):

  • `feature.yml` — writes code + runs tests + commits
  • `bugfix.yml` — same pattern
  • `refactor.yml`, `self-lint.yml`, `self-test.yml`, `self-perf.yml`, `self-improve.yml`, `self-migrate.yml`, `self-audit.yml`, `audit.yml`, `autoloop.yml`, `onboard.yml`, `doc-gen.yml`, `test-gen.yml`, `research.yml`, `deep-research.yml` — likely affected to varying degrees

Unaffected (pure model reasoning, no shell/edit needed):

  • `tri-debug.yml` — three-model diagnosis, all text
  • `tri-dispatch.yml` — routing only

Possible deeper fix

Quick fix unblocks immediately. A stronger fix would be one of:

  1. Per-step enforce: override — add an Enforce field to WfStep in src/engine/workflow.go so individual steps can opt into soft without making the whole workflow soft. Lets security/changelog stay hard while validate/lint/test/create-pr go soft.
  2. Per-step tool allowlist — add allowed_tools: [Bash, Edit] to WfStep; guard reads it and merges into the base allowlist. More surgical than soft, but more work.
  3. Classify by step body — scan `prompt:` text for Bash/Edit/Write keywords and warn at workflow-parse time if the step is hard-enforced. Catches future drift.

Repro

  1. On a branch with commits ahead of main
  2. Run `/devkit:pr-ready`
  3. Observe: validate passes (Bash slips through on first calls — possibly a state-read timing window), but doc-check blocks Edit and create-pr blocks Bash with:
    `BLOCKED: devkit workflow pr-ready step X/9 () is at a prompt step — gather evidence with Read/Grep/Glob then call devkit_advance.`

Related

  • Surfaced in PR refactor(plugin): migrate commands/ to skills/ #77 (commands-to-skills migration)
  • Guard logic: `src/cmd/guard.go:349-364`
  • Step type derivation: `src/mcp/tools.go:260-268`
  • Enforce default: `src/engine/workflow.go:88-90`
  • Intentional block test: `src/cmd/guard_test.go:257`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions