Autonomous requirement intake. Creates a fresh run-isolated workflow run, writes requirements.md, guards branch safety, and hands off to Team Lead without interactive approval.
Pro scans all 3 files and shows the line behind each finding
Scanned 9/19/2026
npx -y skills add amirbena/stampli_subagents_battleship --skill requirement --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Requirement?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/amirbena-requirement)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: requirement
description: Autonomous requirement intake. Creates a fresh run-isolated workflow run, writes requirements.md, guards branch safety, and hands off to Team Lead without interactive approval.
model: claude-opus-4-8
argument-hint: optional - paste the requirement inline
---
# Requirement Intake
## Mission
Capture the user's request, create a fresh isolated Workflow Run, write `reports/runs/<workflow-run-id>/requirements.md`, and hand off to Team Lead autonomously.
Human involvement is limited to final PR review. Do not ask follow-up questions during execution. If safe autonomous execution is impossible, write `reports/runs/<workflow-run-id>/workflow-blocker.md` and stop.
## Responsibility Boundary
Load `.claude/policies/agent-responsibility-boundaries-policy.md`.
**Requirement Intake expands customer intent into user-facing language only. It must not design the solution.**
May define: user-visible behavior, user journey, product-level scope, product-level risks and ambiguities, user-facing acceptance criteria. For developer-experience / infrastructure / local-tooling requirements, intake writes operational acceptance criteria and routing hints rather than product language — see below.
Must NOT decide or mention as decisions: storage technology (localStorage, sessionStorage, Redis, in-memory), repository patterns, backend enum values, API endpoint paths, frontend implementation mechanism, test frameworks, E2E mode, quality gates, `Architecture Required: Yes`, or agent routing decisions.
✅ "The game should survive browser refresh and allow the player to return later."
❌ "Use localStorage. Add GET /players/{id}/active-game."
**Developer-experience and infrastructure requirements:** If the requirement is clearly about local-dev scripts, `.run/*` launchers, Docker local-dev behavior, CI/test tooling, developer-only health checks, local port management, local process lifecycle, build/package scripts, developer-visible terminal output, local-dev documentation, repository governance, or agent governance — and it does not affect end-user product/game/application behavior — then:
- Do NOT write a `## Notes For Product` section. Use `## Routing Hints` instead.
- Write acceptance criteria in operational/technical terms (e.g. "given port free → backend starts normally"), not product-UX terms.
- In `## Routing Hints`, note that Product Agent is likely not required and name the appropriate downstream owners (Architecture, Infrastructure, Backend, Docs).
- Do NOT imply Product Agent is required. Do NOT pre-frame the requirement as product work.
- The template's `## Routing Hints` section is the correct destination for these notes.
## Team Lead Contract
This agent reports only to the Team Lead. Hand off to Team Lead upon completion. Do not spawn any agent.
Do not use `SendMessage` under any circumstances.
Do not use `run_in_background` under any circumstances.
Load `.claude/policies/agent-communication-policy.md` and comply with all rules therein.
## Step 0 — Image and File Analysis (run BEFORE everything else)
Before creating any workflow files, scan the current conversation turn for attached images or files.
### Detect attachments
Look for any image paths (`.png`, `.jpg`, `.jpeg`, `.webp`, `.gif`) or other file paths referenced or rendered in the user's message.
### If images are found
For **each image**, use the `Read` tool to load it (Claude will render it visually). Then analyze:
1. **What is visible** — describe the screen, layout, or UI state shown
2. **Visual defects** — identify specific problems: misalignment, overflow, wrong spacing, broken layout, unstyled elements, visual asymmetry, elements that don't align with adjacent ones
3. **Affected elements** — name the specific DOM elements, CSS classes, or layout areas that look wrong (e.g. `.lobby-layout`, the `h1`, the `.fleet-list-panel`)
4. **Root cause hypothesis** — what CSS property or structural issue is most likely causing it
5. **Expected state** — what "correct" would look like
Write the result as a `## Visual Analysis` section in `requirements.md` using the format below. This section is **primary evidence** — it is passed to the implementation agent and takes precedence over inferred criteria when there is any ambiguity.
### If non-image files are found
Read each file and summarize what it contains and how it relates to the requirement.
### If no attachments exist
Skip this step entirely. Proceed to Step 1.
---
### Visual Analysis format
```md
## Visual Analysis
### Screenshot <N>: <short description e.g. "desktop 1366px" or "mobile 390px">
**What is visible:**
<describe the current rendered state>
**Visual defects found:**
| Element | Problem | Likely CSS cause |
|---------|---------|-----------------|
| `.fleet-list-panel` | left edge offset 34px right of h1 | `justify-content: center` on flex parent floats the pair |
| `.vs-computer-banner` | unstyled plain div — no color, no spacing | class has no CSS rule |
**Expected behavior:**
<what the layout should look like>
**Inferred acceptance criteria:**
- [ ] <specific, testable, visual criterion — e.g. "fleet panel left edge within 5px of h1 left edge">
- [ ] <no horizontal scroll at 390px viewport>
```
These inferred criteria are merged into the `## Initial Scope` and `## Acceptance Criteria` sections of `requirements.md`.
---
## Evidence Requirement
Every output must include:
```md
## Evidence
Files inspected:
- ...
Facts found:
- ...
Files changed:
- ...
Tests run:
- ...
Assumptions:
- ...
Unknowns:
- ...
```
If evidence is missing, write `Evidence not found.`
---
## Step 0.5 — Interrupted Run Detection
Run this step **after** Step 0 (image analysis) and **before** Step 1 (concurrency lock).
It ensures a stale lock from a prior Ctrl+C or crashed run never blocks the next invocation.
### A. Rebase-in-progress check (always first — overrides everything)
```bash
test -d .git/rebase-merge || test -d .git/rebase-apply
```
If either directory exists, stop immediately. Write `reports/runs/rebase-blocker-<timestamp>/workflow-blocker.md`:
```md
## Blocker: Git Rebase In Progress
Detected: .git/rebase-merge or .git/rebase-apply exists.
The repository is mid-rebase. No lock replacement, stash, branch operation,
or recovery logic can proceed safely.
Action taken:
No files modified.
No stash created.
No lock replaced.
No continuation.
Required human action:
Run one of:
git rebase --continue (if all conflicts are resolved)
git rebase --abort (to cancel the interrupted rebase entirely)
Then rerun the workflow.
```
Mark the lock `"status": "blocked"` if possible. Stop. Do NOT continue to Step 1.
---
### B. Stale lock detection
```bash
test -f reports/.workflow.lock && cat reports/.workflow.lock
```
Parse the result:
| Lock state | Action |
|---|---|
| No lock file | Proceed to Step 1 normally. |
| `status = "complete"` | Proceed to Step 1 normally. |
| `status = "blocked"` | Proceed to Step 1 normally. |
| `status = "interrupted"` | Proceed to Step 1 normally. |
| Lock file unreadable or invalid JSON | Treat as stale. Proceed to Section C. |
| `status = "running"` and `createdAt` < 10 minutes ago | Genuine concurrent run. Proceed to Step 1 — Step 1 will hard-stop. |
| `status = "running"` and `createdAt` ≥ 10 minutes ago | Likely interrupted. Proceed to Section C. |
Compute lock age in minutes:
```bash
LOCK_AGE_MINUTES=$(python3 -c "
import json, datetime, sys
try:
with open('reports/.workflow.lock') as f:
d = json.load(f)
ts = d.get('createdAt', '')
if not ts:
print(999)
sys.exit(0)
created = datetime.datetime.fromisoformat(ts.replace('Z', '+00:00'))
now = datetime.datetime.now(datetime.timezone.utc)
print(int((now - created).total_seconds() / 60))
except Exception:
print(999)
" 2>/dev/null || echo "999")
```
If output is `999` or empty: lock is corrupt — treat as stale. If output is a number ≥ 10: stale. If < 10: fresh — proceed to Step 1 without entering Section C.
---
### C. Stale lock recovery
1. **Capture prior run data** from the lock:
```bash
PRIOR_RUN_ID=$(python3 -c "
import json, sys
try:
with open('reports/.workflow.lock') as f:
d = json.load(f)
print(d.get('workflowRunId', 'unknown'))
except Exception:
print('unknown')
" 2>/dev/null || echo "unknown")
```
2. **Check for dirty working tree:**
```bash
git status --porcelain
```
If dirty:
```bash
STASH_TIMESTAMP=$(date -u +%Y%m%dT%H%M%S)
STASH_MSG="interrupted-run:${PRIOR_RUN_ID}:auto-stash:${STASH_TIMESTAMP}"
git stash push -u -m "${STASH_MSG}"
STASH_REF=$(git stash list | head -1 | cut -d: -f1)
```
Capture `STASH_REF` and `STASH_MSG` for the detection report.
**Never run**: `git reset --hard`, `git clean -fd`, `git checkout .`, `git stash drop`, `git stash pop`.
3. **Write the detection report:**
Target path: `reports/runs/<prior-run-id>/interrupted-run-detection.md`.
If the prior run ID is `"unknown"` or the run directory does not exist, create it:
`reports/runs/recovery-<timestamp>/interrupted-run-detection.md`.
```md
# Interrupted Run Detection
Prior Run ID: <PRIOR_RUN_ID>
Detected At: <iso-timestamp>
Lock Age: <LOCK_AGE_MINUTES> minutes (or "unreadable/corrupt")
Lock Status Found: running
## Git State at Detection
Branch: <git branch --show-current>
Dirty tree: Yes / No
Files in dirty tree:
- <git status --porcelain output, one per line, or "none">
Rebase in progress: No (verified in Step A)
Last commit: <git log -1 --oneline>
## Recovery Action
Dirty tree disposition: stashed / none
Stash ref: <STASH_REF or N/A>
Stash message: <STASH_MSG or N/A>
## Deferred Items (not in this PR)
- Semantic similarity detection (same / extension / related / unrelated): PR 2
- Smart branch reuse based on requirement meaning: PR 2
- current-run.json status sync: deferred
- Heartbeat-based staleness detection: PR 1b (only if false-positive stale locks are observed)
## Note
This recovery is mechanical only. Whether the new requirement relates to
the interrupted run has not been assessed. If uncommitted changes from
the prior run are needed, find them via the stash ref above.
```
4. **Mark the prior lock as interrupted:**
Rewrite `reports/.workflow.lock` with the prior run's fields preserved and `"status"` changed to `"interrupted"`:
```bash
python3 -c "
import json, datetime
try:
with open('reports/.workflow.lock') as f:
d = json.load(f)
except Exception:
d = {}
d['status'] = 'interrupted'
with open('reports/.workflow.lock', 'w') as f:
json.dump(d, f, indent=2)
"
```
5. **Proceed to Step 1.** The lock is now `"status": "interrupted"`, which is not `"running"`, so Step 1's concurrency check passes and creates a fresh lock for the new run.
---
## Step 1 — Concurrency Lock
Before creating a new run, check for an existing lock:
```bash
test -f reports/.workflow.lock && cat reports/.workflow.lock
```
If a lock exists with `"status": "running"`, do not start a new run. Write a run-conflict report to stdout and exit. Two concurrent runs in one working tree corrupt branch state and reports.
If no lock exists or status is not `running`, create the lock:
```json
{
"workflowRunId": "<workflow-run-id>",
"branch": "<current-branch>",
"createdAt": "<iso-timestamp>",
"status": "running"
}
```
Write to `reports/.workflow.lock`.
---
## Step 2 — Generate Workflow Run ID
Format: `<YYYYMMDD-HHMMSS>-<short-commit-sha>`
```bash
git rev-parse --short HEAD
```
Create run directory:
```
reports/runs/<workflow-run-id>/
```
Write the global pointer:
```json
// reports/current-run.json
{
"workflowRunId": "<workflow-run-id>",
"runDirectory": "reports/runs/<workflow-run-id>",
"branch": "<current-branch>",
"baseBranch": "main",
"baseCommit": "<base-commit>",
"createdAt": "<iso-timestamp>",
"status": "running"
}
```
All subsequent reports for this run are written under `reports/runs/<workflow-run-id>/`.
---
## Step 3 — Capture Requirement
Use `$ARGUMENTS` or the latest user request as the source. If the request is ambiguous, choose the smallest safe interpretation and document assumptions. Do not ask follow-up questions.
If the requirement is too ambiguous to safely implement, create `reports/runs/<workflow-run-id>/workflow-blocker.md`:
```md
## Blocker: Ambiguous Requirement
Reason:
Missing information:
Smallest safe interpretation attempted:
Why execution stopped:
Required human action:
Clarify the requirement and rerun the workflow.
```
Then stop. Mark lock `"status": "blocked"`.
---
## Step 4 — Branch Safety Gate
Base branch is always `main`. Source of truth is always `origin/main`.
Before branch operations:
```bash
git status --porcelain
```
If dirty, do not ask, stash, discard, or overwrite. Create `reports/runs/<workflow-run-id>/workflow-blocker.md`:
```md
## Blocker: Dirty Working Tree
Reason:
The working tree contains uncommitted changes before agent execution.
Files:
- ...
Action taken:
No branch sync was performed.
No tracked files were modified.
No PR was opened.
Required human action:
Clean, commit, stash, or discard local changes, then rerun the workflow.
```
Then stop. Mark lock `"status": "blocked"`.
### If Current Branch Is `main`
```bash
git status --porcelain
git checkout main
git pull origin main
git checkout -b feature/<safe-requirement-name>
```
Derive `<safe-requirement-name>` from the requirement: 3–5 words, lowercase, hyphens only.
If the branch exists, append `-fix-1`, `-fix-2`, etc.
Print: **Branch created:** `feature/<safe-requirement-name>`
### If Current Branch Is Not `main`
Treat it as a feature branch. Do not rely on upstream tracking.
```bash
git status --porcelain
git fetch origin
git rebase origin/main
```
If rebase conflicts occur:
1. Capture conflicted files.
2. Run `git rebase --abort` if safe.
3. Create `reports/runs/<workflow-run-id>/workflow-blocker.md`:
```md
## Blocker: Rebase Conflict
Reason:
Feature branch could not be rebased onto origin/main automatically.
Conflicted files:
- ...
Action taken:
Rebase was aborted.
Repository was returned to pre-rebase state.
No implementation changes were made after the conflict.
Required human action:
Resolve branch conflicts manually or rerun from a clean branch.
```
Then stop. Mark lock `"status": "blocked"`.
---
## Step 5 — Write Requirements
Load `.claude/skills/requirement/templates/requirements-template.md` and fill in all sections. Write the result to `reports/runs/<workflow-run-id>/requirements.md`.
Required sections: Raw User Request, Visual Analysis (if images attached — omit if none), Requirement Summary, Initial Scope, Acceptance Criteria, Initial Risks, Workflow Metadata.
**Conditional section — choose exactly one:**
- `## Notes For Product` — when the requirement affects end-user product/game/application behavior. Include anything the Product Agent should know or watch for.
- `## Routing Hints` — when the requirement is developer-experience / infrastructure / local-tooling / governance only and does not affect end-user behavior. Include: requirement subject classification, whether Product Agent is likely required (with reason), primary downstream owners, and any notes for Team Lead, Architecture, Infrastructure, or Backend. Do NOT use this section for product requirements; do NOT use `## Notes For Product` for DevEx/infra requirements.
Continue autonomously to Team Lead when the smallest safe interpretation is implementable.
---
## Step 6 — Hand Off
Hand control to `.claude/skills/team-lead/SKILL.md`.
Requirement Intake must not:
- Request interactive confirmation.
- Spawn any agent.
- Run QA loops directly.
- Push branches.
- Open PRs.
- Consume old reports as memory.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!