You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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`):
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:
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.
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.
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
On a branch with commits ahead of main
Run `/devkit:pr-ready`
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.`
Summary
workflows/pr-ready.ymlcannot 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.ymlhas no top-levelenforce:field, so it defaults tohardviavalidate()insrc/engine/workflow.go:88-90. Combined withstepType()insrc/mcp/tools.go:260-268classifying everyprompt:-only step as"prompt", this means every pr-ready step hits theprompt + hardbranch of the guard insrc/cmd/guard.go:349-364— which blocks everything exceptRead,Grep,Glob,TodoWrite,NotebookRead,Skill, and devkit MCP tools.guard_test.go:257assertsprompt+hard+Bash → blockis 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
prompt+hardQuick 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`):
Unaffected (pure model reasoning, no shell/edit needed):
Possible deeper fix
Quick fix unblocks immediately. A stronger fix would be one of:
enforce:override — add anEnforcefield toWfStepinsrc/engine/workflow.goso 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.allowed_tools: [Bash, Edit]toWfStep; guard reads it and merges into the base allowlist. More surgical than soft, but more work.Repro
`BLOCKED: devkit workflow pr-ready step X/9 () is at a prompt step — gather evidence with Read/Grep/Glob then call devkit_advance.`
Related