Skip to content
Back to skills

Collection

ASecurity

Use when a heartbeat needs to check if a story can progress through a gate. Checks prerequisites, dependencies, 3rd-party deps, and child story completion. Called by heartbeat workflows to determine hold_reason transitions.

  • 24 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 8, 2026
databasespythonsqlnodeawstestinggitapidatabase

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 21 files and shows the line behind each finding

Scanned September 8, 2026

npx -y skills add mattnigh/skills_collection --skill collection --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Collection?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Collection
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mattnigh-collection-33d57ee2/badge)](https://www.skillsdirectory.com/skills/mattnigh-collection-33d57ee2)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: gate-routing
description: Use when a heartbeat needs to check if a story can progress through a gate. Checks prerequisites, dependencies, 3rd-party deps, and child story completion. Called by heartbeat workflows to determine hold_reason transitions.
---

# Gate Routing - Story Progression Gates

Check whether a story can progress through various gates, and update hold_reason accordingly.

**Database:** `.claude/data/story-tree.db`

**Critical:** Use Python sqlite3 module, NOT sqlite3 CLI.

## Usage

```
/gate-routing <story_id> <gate_type>
```

**Gate Types:**
- `readiness` - Planning→Implementing: Check 3rd-party deps + prerequisite stories
- `prerequisites` - Implementing (queued): Check if prerequisites are implemented
- `dependencies` - Implementing (blocked): Check if dependency children are planned
- `children` - Releasing (queued): Check if all children are at releasing+

## Gate Definitions

### 1. Readiness Gate (planning-queued → implementing)

Checks two conditions before a story can start implementing:

**A. 3rd-Party Dependencies** (from `dependencies` JSON field)
- External libraries, APIs, services that must be available
- Example: `["redis", "stripe-api", "aws-s3"]`
- **Check:** Verify each dependency is installed/accessible
- **If blocked:** Set `hold_reason = 'blocked'` with note listing missing deps

**B. Prerequisite Stories** (from `prerequisites` JSON field)
- Other story IDs that must complete first
- Example: `["1.2", "3.1.4"]`
- **Check:** Each prerequisite must have `stage IN ('implementing', 'testing', 'releasing') OR terminus = 'shipped'`
- **If blocked:** Set `hold_reason = 'queued'` with note listing pending prerequisites

**If all clear:** Set `hold_reason = NULL` (ready for implementing-nohold)

### 2. Prerequisites Gate (implementing-queued)

Rechecks prerequisite stories only:

```sql
SELECT id FROM story_nodes
WHERE id IN (SELECT value FROM json_each(
    (SELECT prerequisites FROM story_nodes WHERE id = '<story_id>')
))
AND stage NOT IN ('implementing', 'testing', 'releasing')
AND (terminus IS NULL OR terminus != 'shipped')
```

- **If any pending:** Stay `hold_reason = 'queued'`
- **If all complete:** Set `hold_reason = NULL`

### 3. Dependencies Gate (implementing-blocked)

Check if dependency child stories have progressed enough:

A story enters `blocked` when it has children that represent dependencies (plan decomposition created them). These children must reach `planning` stage before the parent can proceed.

```sql
SELECT id FROM story_nodes
WHERE parent_id = '<story_id>'
AND stage = 'concept'
AND terminus IS NULL
```

- **If any children still at concept:** Stay `hold_reason = 'blocked'`
- **If all children at planning+:** Set `hold_reason = 'queued'` (now check prerequisites)

### 4. Children Gate (releasing-queued)

For parent stories to release, all children must be at releasing stage or shipped:

```sql
SELECT id FROM story_nodes
WHERE parent_id = '<story_id>'
AND stage NOT IN ('releasing')
AND (terminus IS NULL OR terminus != 'shipped')
```

- **If any children not at releasing+:** Stay `hold_reason = 'queued'`
- **If all children at releasing+ or shipped:** Set `hold_reason = NULL`

## Implementation

### Step 1: Load Story and Parse Fields

```python
import sqlite3
import json

conn = sqlite3.connect('.claude/data/story-tree.db')
conn.row_factory = sqlite3.Row

story = conn.execute('''
    SELECT id, stage, hold_reason, dependencies, prerequisites
    FROM story_nodes WHERE id = ?
''', (story_id,)).fetchone()

deps = json.loads(story['dependencies']) if story['dependencies'] else []
prereqs = json.loads(story['prerequisites']) if story['prerequisites'] else []
```

### Step 2: Run Gate Check

Based on gate_type argument, run the appropriate check:

```python
def check_readiness_gate(conn, story_id, deps, prereqs):
    """Check both 3rd-party deps and prerequisite stories."""
    issues = []

    # Check 3rd-party dependencies (simplified - just note them)
    if deps:
        # In practice, you'd check if these are actually available
        # For now, assume they're available unless explicitly blocked
        pass

    # Check prerequisite stories
    if prereqs:
        pending = conn.execute('''
            SELECT id, stage, terminus FROM story_nodes
            WHERE id IN ({})
            AND stage NOT IN ('implementing', 'testing', 'releasing')
            AND (terminus IS NULL OR terminus != 'shipped')
        '''.format(','.join('?' * len(prereqs))), prereqs).fetchall()

        if pending:
            issues.extend([f"Prerequisite {p['id']} at {p['stage']}" for p in pending])

    return issues

def check_prerequisites_gate(conn, story_id, prereqs):
    """Check only prerequisite stories."""
    if not prereqs:
        return []

    pending = conn.execute('''
        SELECT id, stage FROM story_nodes
        WHERE id IN ({})
        AND stage NOT IN ('implementing', 'testing', 'releasing')
        AND (terminus IS NULL OR terminus != 'shipped')
    '''.format(','.join('?' * len(prereqs))), prereqs).fetchall()

    return [f"Prerequisite {p['id']} at {p['stage']}" for p in pending]

def check_dependencies_gate(conn, story_id):
    """Check if child dependency stories have reached planning."""
    children_at_concept = conn.execute('''
        SELECT id FROM story_nodes
        WHERE parent_id = ?
        AND stage = 'concept'
        AND terminus IS NULL
    ''', (story_id,)).fetchall()

    return [f"Child {c['id']} still at concept" for c in children_at_concept]

def check_children_gate(conn, story_id):
    """Check if all children are at releasing+ or shipped."""
    pending_children = conn.execute('''
        SELECT id, stage FROM story_nodes
        WHERE parent_id = ?
        AND stage NOT IN ('releasing')
        AND (terminus IS NULL OR terminus != 'shipped')
    ''', (story_id,)).fetchall()

    return [f"Child {c['id']} at {c['stage']}" for c in pending_children]
```

### Step 3: Update Story Based on Result

```python
def update_hold_reason(conn, story_id, new_hold, note=None):
    """Update hold_reason and optionally append to notes."""
    if note:
        conn.execute('''
            UPDATE story_nodes
            SET hold_reason = ?,
                notes = COALESCE(notes, '') || ? || char(10),
                updated_at = datetime('now')
            WHERE id = ?
        ''', (new_hold, f"[gate-routing] {note}", story_id))
    else:
        conn.execute('''
            UPDATE story_nodes
            SET hold_reason = ?,
                updated_at = datetime('now')
            WHERE id = ?
        ''', (new_hold, story_id))
    conn.commit()
```

## Decision Logic

| Gate | Issues Found | Action |
|------|--------------|--------|
| `readiness` | 3rd-party deps missing | `hold_reason = 'blocked'` |
| `readiness` | Prerequisites pending | `hold_reason = 'queued'` |
| `readiness` | All clear | `hold_reason = NULL` |
| `prerequisites` | Any pending | Stay `hold_reason = 'queued'` |
| `prerequisites` | All complete | `hold_reason = NULL` |
| `dependencies` | Children at concept | Stay `hold_reason = 'blocked'` |
| `dependencies` | All children planned+ | `hold_reason = 'queued'` |
| `children` | Children not releasing | Stay `hold_reason = 'queued'` |
| `children` | All at releasing+ | `hold_reason = NULL` |

## Output Format

Report the gate check result:

```
GATE CHECK: {gate_type}
Story: {story_id}
Current hold: {hold_reason}

Checks:
- [PASS/FAIL] {check_description}
- [PASS/FAIL] {check_description}

Result: {CLEAR | BLOCKED | QUEUED}
New hold_reason: {new_value or NULL}
```

## References

- **Database:** `.claude/data/story-tree.db`
- **Schema:** `.claude/skills/story-tree/references/schema.sql`
- **Heartbeat workflows:** `.github/workflows/heartbeat-*.yml`

Files in this skill

  • 0Chan-smc__claude-code-workflow-lab__claude__skills__frontend-dev-guidelines__SKILL.md15.1 KB
  • 17hz__nextjs-template__claude__skills__example-skill__SKILL.md316 B
  • 1ambda__dataops-platform__claude__skills__context-synthesis__SKILL.md3.5 KB
  • 1natsu172__dotfiles__claude__skills__git-analysis__SKILL.md5.4 KB
  • 1natsu172__dotfiles__claude__skills__github-pr-best-practices__SKILL.md7.7 KB
  • 23Maestro__prospect-pipeline__claude__skills__npid-fastapi-skill.md26.1 KB
  • 360AYA25__ClaudeN8N__claude__skills__n8n-code-javascript__SKILL.md15.7 KB
  • 360AYA25__ClaudeN8N__claude__skills__n8n-code-python__SKILL.md17.5 KB
  • 360AYA25__ClaudeN8N__claude__skills__n8n-expression-syntax__SKILL.md9.4 KB
  • 360AYA25__ClaudeN8N__claude__skills__n8n-mcp-tools-expert__SKILL.md12.5 KB
  • 360AYA25__ClaudeN8N__claude__skills__n8n-node-configuration__SKILL.md16.6 KB
  • 360AYA25__ClaudeN8N__claude__skills__n8n-workflow-patterns__SKILL.md11.2 KB
  • 3x-Projetos__claude-memory-framework__claude__skills__scientist__SKILL.md14.8 KB
  • 5MinFutures__futures-arena__claude__skills__migration-tracker__SKILL.md16.2 KB
  • 5MinFutures__futures-arena__claude__skills__planning-guidelines__SKILL.md11.8 KB
  • 92Bilal26__TaskPilotAI__claude__skills__assessment-builder__SKILL.md17.5 KB
  • 92Bilal26__TaskPilotAI__claude__skills__book-scaffolding__SKILL.md19.1 KB
  • 92Bilal26__TaskPilotAI__claude__skills__code-validation-sandbox__SKILL.md6.2 KB
  • 92Bilal26__TaskPilotAI__claude__skills__exercise-designer__SKILL.md18.1 KB
  • 92Bilal26__TaskPilotAI__claude__skills__learning-objectives__SKILL.md24.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…