Skip to content
Back to skills

Find Model Gaps

ASecurity

Find the gaps in the product model — the nodes not yet linked (a capability with no domain, a feature with no capability, a node that serves no business intent), the same thing written twice, the work still missing (a capability with no features, an intent no capability serves) and the screens of a prototype no node covers — and say, for each, the link to make or the play that does the missing work. Every kind is written on its own (ADR 043), so the model holds loose nodes until they are link...

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
toolspythongobashnode

Security analysis

A100/100

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

Scanned November 7, 2026

npx -y skills add intent-driven-ai/garura --skill find-model-gaps --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Find Model Gaps?

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

Security grade badge for Find Model Gaps
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/intent-driven-ai-find-model-gaps/badge)](https://www.skillsdirectory.com/skills/intent-driven-ai-find-model-gaps)

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: find-model-gaps
description: Find the gaps in the product model — the nodes not yet linked (a capability with no domain, a feature with no capability, a node that serves no business intent), the same thing written twice, the work still missing (a capability with no features, an intent no capability serves) and the screens of a prototype no node covers — and say, for each, the link to make or the play that does the missing work. Every kind is written on its own (ADR 043), so the model holds loose nodes until they are linked; this skill finds them. Its script counts the candidates; the judgment (is this really a gap, where does this node belong, which play owns the work) is the skill's. Writes gaps.json; never writes the model. Used by the shared loop run after each round, through product-os-keeper; later plays that show or fix the model's gaps can reuse it.
user-invocable: false
model: sonnet
allowed-tools: Read, Write, Glob, Grep, Bash
---

# find-model-gaps

The product model is written in pieces (ADR 043): `/discover-intent` writes business intents,
`/discover-domains` domains, `/discover-capabilities` capabilities and features, each on its own. A piece is
not ready until it is linked — feature → capability → domain, and its agent intent to a
confirmed business intent. This skill finds what is not linked yet, what is written twice, and
what is still missing, and says what to do about each.

## Input

| Field | Required | Meaning |
|-------|----------|---------|
| `product_base` | yes | The project's product base; the model is under `<product_base>product-os/`. Read only. |
| `journeys` | no | A prototype's `journeys.yaml` (its `main_sections`), from the shared capture. |
| `view_texts` | no | The folder of the capture's view texts (`view-*.txt`). |
| `write_up` | no | The person's short write-up of the prototype (what it is, who uses it, the field and the job, the sample data, the walkthrough). |
| `out` | yes | Where to write `gaps.json`. |

## Process

1. **Count the candidates.** Run the script; it reads the spine, the pages and the capture:

   ```bash
   python3 scripts/find_gaps.py --product-base <product_base> \
       [--journeys <journeys.yaml>] [--view-texts <view texts folder>] \
       --out <working>/gap-candidates.json
   ```

   It lists: nodes with no parent (`unattributed`), parents named that do not exist
   (`dangling`), capabilities with no feature, intents no node serves, nodes that serve
   no intent, links to an intent held on one side only (`one_way` — the node's `intents` names
   the intent but the intent page's Touches list does not name the node, or the reverse), empty
   domains, likely duplicates (titles that match once normalised) and screens no page's
   `## Sources` names (`uncovered`).
2. **Judge each candidate.** Every `one_way` entry is a gap: a link is made only when both
   sides hold it. Give each one a `links_to_make` entry with `field: intents`. For the other
   candidates, read the pages and their `## Sources`. Clear a candidate that is not a gap (two
   titles that only look alike). Confirm the rest.
3. **Propose each link, with why.** For a loose node, name where it belongs — the capability
   a feature is part of, the domain a capability sits in, the intents a node serves —
   from what the pages and their sources say, and say why in one plain line. Never invent a
   parent: when no node fits, it is missing work (step 5), not a link.
4. **Agree the duplicates.** For two nodes that are the same thing, name which to keep (the
   one with more content and sources) and mark it `agreed: true` only when the pages and
   their sources show the same screen and the same purpose.
5. **Give each piece of missing work to the play that does it:**
   - a capability with no features → `/discover-capabilities`;
   - a capability no domain holds, and no domain fits → `/discover-domains`;
   - a screen's need that no business intent names → `/discover-intent`;
   - an intent no capability serves → `/discover-capabilities`;
   - a screen no capability or feature covers → `/discover-capabilities`.
6. **Write `gaps.json`** in the shape under Output.

## Output

`gaps.json`, at `out`:

```json
{
  "links_to_make": [{"kind": "capability", "id": "<id>", "field": "domain | capability | intents",
                     "value": "<parent id, or [intent ids]>", "why": "<one plain line>"}],
  "duplicates": [{"kind": "capability", "keep": "<id>", "drop": "<id>", "agreed": true, "why": "…"}],
  "work": [{"play": "/discover-capabilities", "target": "<id or screen>", "why": "<one plain line>"}],
  "uncovered": [{"what": "main section | view", "name": "…"}],
  "cleared": [{"candidate": "…", "why": "…"}]
}
```

## Rules

- **Read only.** This skill writes `gaps.json` and nothing else. `link-model-gaps` applies it.
- **No link without a basis.** Every link and every merge says why, from the pages, their
  sources, the capture or the write-up.
- **Work goes to the play that owns the kind** (ADR 043): intents to `/discover-intent`, domains to
  `/discover-domains`, capabilities and features to `/discover-capabilities`.
- **Plain words.** Each `why` is one short sentence a person reads without the model open.

Files in this skill

  • SKILL.md5.1 KB
  • scripts/find_gaps.py9 KB
  • scripts/intent_touches.py5.3 KB
  • scripts/model_names.py4.1 KB
  • scripts/test_find_gaps.py6 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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.