Skip to content
Back to skills

Sd Intent Review

ASecurity

The first service-design step: read a repo's intent document and produce a research agenda -- candidate services to test and claims to test -- with every item tracing to an intent field. Outputs hypotheses to validate against real discourse, never designed services. Invoke at the start of a repo's service design, before any artifact exists.

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 23, 2026
ai-agentsgobashtesting

Security analysis

A100/100

Scanned September 27, 2026

npx -y skills add runlegion/legion --skill sd-intent-review --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sd Intent Review?

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

Security grade badge for Sd Intent Review
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/runlegion-sd-intent-review/badge)](https://www.skillsdirectory.com/skills/runlegion-sd-intent-review)

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: sd-intent-review
description: |
  The first service-design step: read a repo's intent document and produce a research
  agenda -- candidate services to test and claims to test -- with every item tracing to an
  intent field. Outputs hypotheses to validate against real discourse, never designed
  services. Invoke at the start of a repo's service design, before any artifact exists.
version: 0.3.0
user-invocable: true
allowed-tools: Bash, Read
---

# Intent review: intent in, research agenda out

This step steps BACK from the intent, not forward from it. Its output is what to go ask
the world about -- not services, not artifacts, not statuses. The one failure mode that
matters: over-producing. A reviewed intent that comes back with system responses, real
versus planned stamps, or merged service definitions has jumped two steps ahead; that is
service design, and it happens only after the claims are tested.

## What the intent commits, and what it leaves open

Not every statement in an intent is a hypothesis. A `direction.proposals` entry marked
`settled`, the `what_it_is` framing, and the intent's `boundaries` are the operator's
committed direction: Discovery informs HOW these are designed, never WHETHER they are
needed. An intent may say so outright -- one repo's `meta.purpose` reads "every direction
item is required; Discovery informs how each is designed and does not decide whether it is
needed." Derive a service or claim to test ONLY from what the intent leaves genuinely open:
proposals carrying `needs_pressure_test`, the intent's `claims[]` test cards, unresolved
`open_questions`, and `current_state.cut_or_broken` whys that no settled proposal already
commits to fixing. A `cut_or_broken` why that is the rationale for a settled proposal is
committed alongside that proposal -- testing it relitigates the committed fix through
the `cut_or_broken` door, so it gets no test. Never derive a test from a `boundary`, from
`what_it_is`, or from a `settled` proposal that carries no `needs_pressure_test` flag.

A proposal has two independent fields (`status: proposed|settled` and a `needs_pressure_test`
boolean); classify by both, so no combination falls through. `needs_pressure_test: true`
marks it a hypothesis to test whatever its status -- the operator asked for the test, so this
wins even on a `settled` proposal. Otherwise a `settled` proposal is committed and gets no
test, and a `proposed` proposal carrying no flag is UNDECIDED -- neither committed nor a
stated bet -- so escalate it to the operator as an open direction to resolve (report it under
`escalations`, step 5), never silently test it or treat it as committed. This first step does
not read the intent's prose to GUESS a proposal's commitment the way the later `sd-write-spec`
does; with no discovery evidence in hand yet, it escalates rather than judges -- the two steps
meet the same schema shape with different licenses by design. An intent whose direction is
fully committed, with no `claims[]` test cards, yields an
EMPTY agenda -- that is correct, not a failure, and sd-discover then only grounds how.
Manufacturing claims against a committed direction is over-producing in its most damaging
form: it hands the operator's bet to outside discourse to relitigate.

## Gate: distill the intent first

Before deriving anything, cold-read the intent against distill (the checks in the
`legion-distill` skill). You are a fresh reader of this intent, so you are the cold reader
distill needs -- no separate agent. Judge whether you can act on the intent from its own
text alone. A stop is any of: a claim that does not carry its own substance, a bare pointer
to another id or document a reader would have to fetch to act, or a block that contradicts
another. At a stop, HALT -- emit the specific gaps and derive no agenda. A schema-valid
intent can still stop here: `document validate` checks the shape, distill checks whether a
reader can follow it. Do not smooth a gap into an agenda item; an intent that fails distill
goes back to its writer, not forward to a review.

## Procedure

1. Read the intent in full: `legion document view <intent-id> --json`. The fields that
   feed the agenda: `what_it_is` (the reason to exist -- read for context and the distill
   gate, never itself an agenda item), `direction.becoming` and its proposals,
   `current_state.cut_or_broken` (an entry's `why` is a claim only when no settled
   proposal already commits to fixing it -- see "What the intent commits"),
   `current_state.known_gaps` where present, `open_questions` (unresolved ones ARE agenda
   items), and `evidence` (existing lenses and crawl topics constrain where proof can come
   from).

2. Derive **services_to_test**: for each genuinely-open service the intent implies (see
   "What the intent commits" -- a service wholly under settled proposals is committed and
   gets no test; a service part-committed and part-open gets a test scoped to its open part
   only), one entry `{name, actor, goal, test}` where `test` states what real discourse
   would confirm the need exists. Lightweight hypotheses only -- no `system_response`, no
   real/planned status, no merging or splitting of services. If two candidate services
   blur together, list both; sd-discover's evidence will sort them. A service with two
   actors names the primary in `actor` and the second inside `goal`.

3. Derive **claims_to_test**: for each genuinely-open claim (see "What the intent commits";
   start from `needs_pressure_test` proposals, `current_state.cut_or_broken` whys that no
   settled proposal already commits to fixing, unresolved `open_questions`, and its
   `claims[]` test cards where present -- never a settled proposal, a `boundary`, or a
   `what_it_is` assertion), one entry
   `{claim, who, evidence_target, right_if}` where `evidence_target` names the
   lens (or lens-to-be) and the query that would surface it, and `right_if`
   states what result confirms or kills it, as a comparison sd-discover can run (the
   claim's hits against a same-lens control, or a census count), never a score bar.
   Every entry names the intent field it came from. When the only lens is the
   intent's `crawl_topic` (`needs_crawl` true), label that lens-to-be CRAWL and define the
   mapping once at the top of the agenda so downstream steps can match on it. An
   unresolved open_question lands as a claim when it doubts a need, as a service test when
   it doubts a mechanism -- and may split into one of each. Each entry also carries a
   `key`: the intent's `claims[].id` when the entry came from a test card, otherwise the
   entry's 1-based position in `claims_to_test`. The key is what the prediction
   fingerprint is built on (Instrumentation below), and sd-discover reads it from the
   agenda to witness the claim, so it never changes once the agenda is handed on.

4. **Emit the predictions** (see Instrumentation below): one per `claims_to_test` entry,
   after the agenda is final so every fingerprint names a key sd-discover will read.
   Write each returned prediction id into its entry as `prediction`; the agenda is the
   handoff, and the witness needs the id.

5. Report the agenda to the caller as structured text: **services_to_test** and
   **claims_to_test** (each item with its intent trace, its key, its prediction id, and the
   claimed confidence), and **escalations** -- the UNDECIDED proposals (`proposed` and
   carrying no `needs_pressure_test` flag), each named with the ruling the operator owes and
   a recommended answer with its reasoning, so the operator can settle it in one line. This
   step writes no legion document; the agenda is working state, and handing it to the next
   step as a scratch FILE is fine -- a file is not a document, and the prohibition is on
   store writes, not on writing the agenda down. When the agenda carries any escalation the
   direction is not yet fully classified: park per the protocol in the sd-service-design
   skill (Park and resume) for the operator's rulings before sd-discover runs. If the session
   must stop here for any reason, park the same way, with the agenda, prediction ids, and
   escalations included in the anchor text.

## Instrumentation

This step's one judgment is which claims the world will bear out. Deriving the agenda is
not a prediction -- every entry traces to an intent field by rule -- so the agenda itself
gets no emission. Each claim to test does: one prediction per entry, under this skill's
name, that sd-discover will return it `supported` or `bounded`. The number is what makes
the review accountable for the intent's optimism instead of a relay of it. The prediction
row is the engine's, not a document; the rule against store writes here is about
artifacts, and a prediction is not one.

Stake each claim from the intent's own evidence fields, not from how much the intent
wants it. Anchors: a claim from a `claims[]` test card whose `right_if` names a query a
lens already in `evidence.lenses` can answer sits near 0.7; a claim implied by a
`cut_or_broken` entry's `why`, with a lens, sits near 0.5; a claim whose only lens is the
CRAWL lens-to-be, or one raised by an open question that doubts the need, starts near
0.3. From the anchor, move by what the intent already cites: a `meta.sources` entry of
kind `audit` or `reflection` that reports the pain firsthand moves the number up; a
`known_gaps` entry admitting the pain has not been observed moves it down. Different
claims get different numbers; an agenda emitted at one value teaches the estimator
nothing about which kinds of claim the intent gets wrong.

```
legion uncertainty emit --surface legion.sd --feature-key sd.intent-review.claim \
  --session-id "$CLAUDE_CODE_SESSION_ID" --orphan-ttl-days 180 \
  --input-fingerprint <intent-id>:claim:<key> --claimed-confidence <p> \
  --payload '{"intent":"<intent-id>","key":"<key>","from":"<intent field>","lens":"<lens>"}'
```

The emit mechanics -- session id and model, the exit-0 rule, the 180-day orphan window,
non-blocking emission, never self-witnessing -- are held once in the sd-service-design
skill (Instrumentation, "Emit mechanics") and bind here. What is this step's alone: the
check is each fingerprint against the agenda entry it names, and since no document
lands, the agenda file and the report carry the ids.

**Who witnesses, and when.** sd-discover, at its authoritative scoring pass, when it
lands a verdict on the claim. It reads the entry's `prediction` id from the agenda,
confirms it by rebuilding `<intent-id>:claim:<key>`, and witnesses by the verdict:
`supported` is `shipped` at 1.0, `bounded` is `scoped-down` at 1.0 (support within
limits is still support), `contradicted` is `abandoned` at 0.0. A `blocked` insight
leaves the prediction unwitnessed: no verdict was reached, the wake may still reach one,
and a corpus that never does lets the orphan sweep retire it, which is right for a claim
never tested. A `saturated-unevidenced` insight also leaves it unwitnessed: silence
argues against the claim without being discourse that disputes it, and scoring it 0.0 would
teach the estimator that silence is contradiction, the confusion the no-evidence rule
exists to prevent. The discover report names each claim left unwitnessed and why.

## Refuses

- Designing services: any output field beyond `{name, actor, goal, test}` per service.
- Stamping build status: real versus planned is build state and belongs to later steps.
- Inventing claims the intent neither states nor implies -- an emergent insight is
  sd-discover's to discover from evidence, not this step's to guess.
- Deriving a service or claim to test from a `boundary`, from `what_it_is`, from a `settled`
  proposal that carries no `needs_pressure_test` flag, or from a `cut_or_broken` why that a
  settled proposal already commits to fixing: a committed direction is designed, not
  relitigated. An all-settled intent with no `claims[]` test cards has an empty agenda.
- Silently dropping a `proposed` proposal that carries no `needs_pressure_test` flag: it is
  undecided, so escalate it to the operator, never guess it committed or open.
- Reviewing an intent that does not exist, does not validate, or does not pass the distill
  gate (above): stop and emit the gaps.
- Witnessing its own predictions. The review stakes them; sd-discover's verdicts score
  them. A self-witnessed claim is the rubber stamp the engine exists to catch.

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.