blockers
Skill1 starsChanged 7 months agoMITView on GitHub
Track external blockers that need user input (API keys, scope decisions, vendor selections, CPA reviews) outside the chat. Use when the user runs /blockers, /blockers <id-or-name>, /blockers resolved, /blockers add, or /blockers check. Also surface this skill proactively when a workstream is parked because of a missing key, a deferred architecture decision, or any "needs founder input" condition — offer to register it as a blocker.
- Reads credentials
1 other project uses a version of this.
Adopted by
Most recently taken up by
- veraetogrex-portfolio/solo-sddtheir own version, first seen Nov 15, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- veraetogrex-portfolio/solo-sdd★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. About 0 are common, 5 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 28
Every blocker carries these fields:
- Very specific: line 69
Default action. Print the table view of every unresolved blocker, sorted by urgency (P0 first), then by daysOpen desc within each urgency …
- Very specific: line 81
After the table: N unresolved (P0: x, P1: y, P2: z, P3: w) · M resolved-detected · K resolved.
- Very specific: line 95
After any state change, append a one-line entry to the ## Resolution log section at the bottom of blockers.md with timestamp + actor (user) …
- Very specific: line 120
After confirmation, append a new YAML block to blockers.md under the ## Blockers section.
- Distinctive: line 125
Read the named env file.
- Distinctive: line 126
Check whether each listed env var is present and non-empty.
- Very specific: line 127
If all vars present → flip status to resolved-detected (or stay there).
- Very specific: line 128
If any vars missing → keep status as unresolved.
- Very specific: line 138
Never write secrets anywhere: Not to blockers.md, not to a log file, not to the chat output.
- Very specific: line 143
When refused, tell the user: "drop that into <app>/<env-file> directly, then run /blockers check."
- Very specific: line 147
Cross-app aware display: Always show the app field in the table view AND the focused-card view.
- Very specific: line 284
Prefix collision rule: if two apps share a prefix, /blockers add refuses and asks the user to disambiguate.
- Distinctive: line 290
When the assistant hits a wall that the user could resolve but the assistant cannot — a missing API key, a deferred architecture decision …
- Distinctive: line 294
Do NOT auto-register. The user opts in.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/blockers — workspace blocker registry
A workspace-scoped registry for things the assistant cannot resolve on its own — API keys, vendor selections, architectural decisions, regulatory engagements, anything that needs information from outside the chat.
The user invokes this with /blockers [subcommand]. The skill is the file at .claude/skills/blockers/ plus a hand-curated registry at the workspace root.
Files this skill reads and writes
| Path | Purpose | Editable by skill? |
<workspace-root>/blockers.md | The registry. Hand-seeded once; the skill flips status fields and updates daysOpen on every read. | Yes — status, resolvedAt, and daysOpen only. Never overwrites the body. |
<workspace-root>/blockers.config.yaml | Workspace setup (apps, env file paths, app prefixes). Created once at install. | Read-only after install. |
<app>/.env, <app>/.env.local, <app>/.env.example | Source of truth for resolved env-var blockers. | Read-only. The skill never writes secrets to any file. |
Path resolution. The skill always operates at the workspace root (the directory that contains blockers.md). If blockers.md is missing, the skill prompts the user to copy .claude/skills/blockers/template-blockers.md to the workspace root and .claude/skills/blockers/template-config.yaml to blockers.config.yaml.
Blocker fields
Every blocker carries these fields:
| Field | Required? | Type | Purpose |
id | yes | string | Numerical app-prefixed identifier, e.g. LD-0001 (Ledger blocker #1). Auto-allocated by /blockers add per-app. |
name | yes | string (slug) | Human-readable slug, e.g. stripe-sandbox-keys. Used in URLs, log lines, and dependsOn references. |
title | yes | string | One-line description shown in cards. |
app | yes | string | App key from blockers.config.yaml. |
type | yes | enum | env-var | architecture-decision | scope-decision | external-engagement | provider-port |
urgency | yes | enum | P0 | P1 | P2 | P3 (see below) |
status | yes | enum | unresolved | resolved-detected | resolved-confirmed | superseded | wontfix |
date | yes | ISO date | Date the blocker was added/identified (YYYY-MM-DD). Set once at registration; never edited. |
daysOpen | derived | integer | Days from date to today (computed live by the skill on every render; not persisted as the source of truth — date is). For resolved-confirmed blockers, days from date to resolvedAt. |
workstreams | yes | string[] | Workstream IDs gated by this blocker. |
envVars | yes for env-var | string[] | Env var names to drop into the configured env file. Never values. |
source | optional | string | Pointer to the plan/doc that scoped this blocker. |
unblocks | yes | string | Free-text. What work proceeds once resolved. |
needed | yes | string | Free-text. What the user has to do/find/decide. |
notes | optional | string | Free-text. |
dependsOn | optional | string[] | Names (not numerical ids) of other blockers that must resolve first. |
resolvedAt | optional | ISO datetime | Set on transition to resolved-confirmed. |
Urgency scale (P0 highest)
- P0 — Critical. Production blocked, money on the line, or cannot ship anything until resolved.
- P1 — High. Blocks a workstream that's active or near-term (current quarter).
- P2 — Medium. Blocks a planned workstream (next quarter or two).
- P3 — Low. Blocks future / nice-to-have work; safe to defer indefinitely.
Numerical id format
<PREFIX>-<NNNN> where <PREFIX> is the 2-letter (uppercase) prefix declared per-app in blockers.config.yaml, and <NNNN> is a zero-padded 4-digit sequence number unique within that prefix. Example: LD-0001, LD-0002, AU-0001, AM-0001.
Allocation: /blockers add auto-assigns the next available number for the chosen app. The user never types the numerical id when adding; it's deterministic.
Subcommands
/blockers (no args)
Default action. Print the table view of every unresolved blocker, sorted by urgency (P0 first), then by daysOpen desc within each urgency band (older = higher).
ID NAME APP URGENCY TYPE DAYS WORKSTREAMS BLOCKED
LD-0006 advisor-portal-architecture ledger P1 architecture-dec. 14 W4.4.3
AU-0001 stripe-sandbox-keys auth P1 env-var 14 W2.2.4
LD-0007 cpa-review-engagement ledger P1 external-engagement 14 W1.3
AU-0005 vip-tier-thresholds-final auth P1 scope-decision 14 W0.5
LD-0004 plaid-production-keys ledger P2 env-var 14 W1.2.7
...After the table: N unresolved (P0: x, P1: y, P2: z, P3: w) · M resolved-detected · K resolved.
End with: Run /blockers <id-or-name> to focus one, or /blockers resolved to see the resolved log.
Both LD-0006 and advisor-portal-architecture resolve to the same blocker — the skill accepts either form for <id-or-name> arguments.
/blockers <id-or-name>
Focus one blocker. Display the full card (see "Display format"). Then interactively resolve based on type:
env-var: confirm the env vars listed are now in the named env file. Run/blockers checkagainst this single id (grep the env file for each var name). If all present → markresolved-detected+ ask user to confirm. If any missing → tell the user exactly which file + which var name to add. NEVER prompt the user to paste the secret value into the chat. NEVER write the secret to any file.architecture-decision/scope-decision: prompt the user inline for the decision. The answer IS the resolution and gets persisted to the registry.external-engagement: record the engagement status (e.g. "engaged with KPMG UK 2026-04-30, expected memo 2026-06-15"). Resolution timeline lives in the notes, not in the status field — these blockers stayunresolveduntil the deliverable lands.provider-port: record where the provider keys live (env var name + file path) + that the port itself is mechanical work the next session can pick up.
After any state change, append a one-line entry to the ## Resolution log section at the bottom of blockers.md with timestamp + actor (user) + id + name + new status + brief reason.
/blockers resolved
Show the resolved log — the bottom section of blockers.md. Read-only; no prompts. Useful for sanity-checking what was unblocked when. Each row shows daysOpen at the time of resolution (not live).
/blockers add
Interactive add-a-new-blocker flow. Prompt for each field in order:
name(required, slug — typically<short-name>orW<workstream>-<short-name>)title(required)app(required — must match a key inblockers.config.yaml; the skill auto-derives the numerical id from the app's prefix + next available sequence number)type(required — one of:env-var,architecture-decision,scope-decision,external-engagement,provider-port)urgency(required —P0/P1/P2/P3)workstreams(comma-separated workstream IDs that this blocker gates)- For
env-var: list of env var names (one per line, blank to finish) - For
architecture-decision/scope-decision: the decision being asked for - For
external-engagement: engagement type + counterparty (e.g. "CPA review, UK Big Four") needed(free text — what the user has to do/find/decide)unblocks(free text — what work proceeds once this resolves)notes(optional)
Auto-set: id (next available <prefix>-<NNNN> for the named app), date (today), status (unresolved).
After confirmation, append a new YAML block to blockers.md under the ## Blockers section.
/blockers check
Pure scan, no prompts. For every env-var blocker:
- Read the named env file.
- Check whether each listed env var is present and non-empty.
- If all vars present → flip status to
resolved-detected(or stay there). - If any vars missing → keep status as
unresolved.
Print a delta report: 2 blockers transitioned to resolved-detected, 0 stayed unresolved, 1 blocker has missing env file (auth/.env not found).
Never reports the values of env vars — only their presence. Output goes to the chat; treat it as a one-off audit.
Hard rules
- Never write secrets anywhere. Not to
blockers.md, not to a log file, not to the chat output. Refuse if the user pastes a secret. Specifically refuse strings matching:sk_test_*,sk_live_*,pk_test_*,pk_live_*(Stripe)AKIA*,ASIA*(AWS)- Strings >40 chars of mixed-case alphanumerics + base64 chars
- Anything the user labels as "secret", "key", "token", "password" inline
When refused, tell the user: "drop that into
<app>/<env-file>directly, then run/blockers check."
- Auto-detected resolution is provisional.
resolved-detectedis the auto state; only the user's explicit confirmation flips it toresolved-confirmed. A stray env var should never silently mark a blocker done. - Never delete a blocker from
blockers.md. Resolution is a status flip + log append, not a deletion. The audit trail is load-bearing. - Numerical ids are immutable + monotonic. Once
LD-0007is allocated, that number is permanently associated with that blocker even if it's later markedwontfixorsuperseded. New blockers get the next available number, never a recycled one. The 4-digit padding gives 9 999 blockers per app — overflow is not a concern at human scale. - Cross-app aware display. Always show the
appfield in the table view AND the focused-card view. A blocker that affects multiple apps lists each one separated by+(e.g.auth + admin). - Lifecycle integration: when a blocker resolves to
resolved-confirmed, scanblockers.mdfor any other blockers whosedependsOnfield references the resolved blocker'sname, and list them as "now potentially unblocked." Then offer to open the next round of work that the unblocked workstream(s) cover. Do NOT touchwealth-migration.mdor any other plan file from this skill — surfacing the next step is enough; the user runs the actual work through normal session flow.
Status values
unresolved— initial state.resolved-detected— automated detection (env-var scan) flipped this. Awaiting user confirmation.resolved-confirmed— user confirmed the blocker is resolved. Logged in the resolution log.superseded— the requirement changed. Body of the entry should explain how.wontfix— the workstream this gates is being deprioritised or deprecated. Body should explain.
State transitions:
unresolved→resolved-detected(auto, env-var only)unresolved→resolved-confirmed(user, any type)resolved-detected→resolved-confirmed(user)resolved-detected→unresolved(user, if the auto-detection was wrong)- any →
supersededorwontfix(user)
Display format
Table row (list view)
ID NAME APP URGENCY TYPE DAYS WORKSTREAMS BLOCKEDFixed-width columns. Truncate workstreams if more than 3 fit (W2.2.4, W3.3.4, W3.3.5 +1 more). Truncate type to first 18 chars + . if needed.
Focused card (single blocker)
[<id>] <name> — <title>
App(s): <app> (or app1 + app2)
Urgency: <P0|P1|P2|P3>
Type: <type>
Status: <status>
Date added: <YYYY-MM-DD> (<daysOpen> days ago)
Workstreams blocked: <comma-separated>
Source: <plan or doc reference>
Needed:
<free text — what the user has to do>
Resolution target:
[env-var] Drop these vars in <app>/<envFile>:
- VAR_NAME_ONE
- VAR_NAME_TWO
[architecture-decision] Answer the question inline.
[external-engagement] Track engagement status in notes.
[provider-port] Drop keys then a future session does the port work.
Unblocks once resolved:
<free text — what work proceeds>
Notes:
<optional free text>
Resolution log:
<if any history exists, last 3 entries>Registry file format (blockers.md)
Markdown with YAML blocks. The skill reads YAML between ```yaml fences and renders the surrounding markdown verbatim. Top of file holds the ## Configuration section (a pointer to blockers.config.yaml for human reference); ## Blockers holds one block per blocker; ## Resolution log is append-only at the bottom.
A blocker entry:
## [LD-0001] truelayer-sandbox-keys — TrueLayer sandbox API keys
```yaml
id: LD-0001
name: truelayer-sandbox-keys
title: TrueLayer sandbox API keys
app: ledger
type: env-var
urgency: P2
status: unresolved
date: 2026-04-28
workstreams: [W1.2.4]
envVars:
- TRUELAYER_CLIENT_ID
- TRUELAYER_CLIENT_SECRET
- TRUELAYER_REDIRECT_URI
source: ledger/docs/plans/wealth-migration.md § W1.2.4
unblocks: |
W1.2.4 -- TrueLayer bank-feed provider port (UK + EU coverage via PSD2 Open Banking).
needed: |
Sign up at https://console.truelayer.com (free sandbox tier), copy client_id and client_secret into ledger/.env.
notes: |
Highest-leverage second provider after Plaid -- covers UK + 11 EU countries with one API.
```Body text below the YAML block is free-form notes editable by the user. The skill never overwrites it; only the YAML's status, resolvedAt, and daysOpen fields.
Workspace config file format (blockers.config.yaml)
# Apps in this workspace. Each entry maps an app key to its repo path
# (relative to workspace root), its env file (relative to workspace
# root), and a 2-letter uppercase prefix used for numerical blocker
# ids. The skill uses these to:
# - validate that a blocker's `app:` field is known
# - locate the env file when running /blockers check on env-var blockers
# - allocate numerical ids (<prefix>-NNNN) per-app
# - render the env-var resolution target in the focused card
apps:
- key: ledger
prefix: LD # 2-letter uppercase; must be unique across apps
path: ./ledger
envFile: ./ledger/.env
- key: admin
prefix: AM
path: ./admin
envFile: ./admin/.env.local
- key: auth
prefix: AU
path: ./auth
envFile: ./auth/.env
# ... add one entry per app/repo in your workspace
# Optional: where the registry file lives. Defaults to ./blockers.md.
registry: ./blockers.mdFor single-repo projects, apps may have one entry with key: app, prefix: AP, path: .; the skill works the same way.
Prefix collision rule: if two apps share a prefix, /blockers add refuses and asks the user to disambiguate.
When to invoke this skill proactively
When the assistant hits a wall that the user could resolve but the assistant cannot — a missing API key, a deferred architecture decision flagged in a plan file, a "needs founder input" comment, an external regulatory dependency — offer:
"This is parked on
<X>. Want me to register it as a blocker so /blockers tracks it?"
Do NOT auto-register. The user opts in. Auto-registration would clutter the registry with speculative blockers.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

