microsoft/attractorify
> Analyze the current session and decide whether an attractor pipeline is "should this be an attractor?", "design a pipeline for", "attractorify this", "do I need an attractor pipeline?", "turn this into a pipeline".
npx skills add https://github.com/microsoft/amplifier-bundle-attractor --skill attractorify
This skill runs inline in the current session (not as a forked sub-session)
so it can read the full conversation context, files, and task state — a forked
execution with default context_depth=none would see nothing of the session
it is supposed to analyze (the council/council-here precedent).
Apply the three-question test from docs/PIPELINE_DESIGN_PRINCIPLES.md §0
("The three-question test") before designing anything:
Answer all three against the capability the user is asking for, not only the
work already in front of you: an explicit request for a repeatable, rerunnable
mechanism with a machine-checkable gate for future recurrences makes the test
prospective — and the quote you cite below is the user's request for that
future loop. The honest no is reserved for asks with no machine gate.
**The diagnosis is not a judgment you hold in your head — it is a file you
write.** Write .attractorify/diagnosis.md under the working directory
(mkdir -p .attractorify first), in exactly this shape:
# /attractorify diagnosis
work: <one line naming the work being diagnosed>
Q1 (cycle): <yes|no>
Q1 quote: "<direct quote — the user's own words, or observed repo state>"
Q2 (evidence-gated exit): <yes|no>
Q2 quote: "<direct quote>"
Q3 (bad-day survival): <yes|no>
Q3 quote: "<direct quote>"
verdict: <attractor|recipe|one-shot|existing-attractor>
counter: "<the strongest quote AGAINST the verdict>" — <one-line honest disposition>
status: <FINAL, or: PROVISIONAL — asked: the clarifying questions posed>
budget: max <N> nodes; gates: <the evidence gates that justify them>
Rules of construction:
repo state (a path plus what it shows) — predating and independent of
anything this skill itself suggested. **Assent to a skill-proposed option,
menu, or checklist is NOT evidence: if you proposed it, you cannot cite
agreement with it.** A "yes" without a supporting quote is invalid by
construction — when the session contains no determinative user-originated
evidence for a question, write Q<n> quote: NO EVIDENCE IN SESSION
instead, which forces either an honest "no" or a clarifying question
(Step 2); it can never support a design.
user explicitly defers a question ("your call", "no strong opinion", "you
decide"), DERIVE the answer from the strongest session evidence: quote the
deferral on the quote line, and mark the answer line
<yes|no> — derived (user-delegated): <the basis> — e.g.
`Q1 (cycle): yes — derived (user-delegated): the machine-checkable
retry-until-green DoD constitutes the loop`. Do not bounce the deferred
question back to the user — exercising the delegated judgment is the
answer they asked for.
user's or the repo's own terms (a test suite, an exit code, an observable
state). Enthusiasm, schedule pressure, and complaints are real quotes but
are not evidence of a gate.
counter: line is required: quote the strongest thing in thesession AGAINST your verdict, then disposition it honestly in one line —
rebut it with user-originated evidence, or concede and change the verdict.
Engineering around the counter-quote is the named failure this line exists
to surface.
status: is PROVISIONAL — asked: ... whenever any answer lackeddeterminative evidence and clarifying questions went out.
budget: line is required when the verdict is attractor orexisting-attractor (or an override is present): a hard node cap justified
by naming the evidence gates the topology serves. Machinery no named gate
asks for is bloat. For existing-attractor, the budget must additionally be
machine-encoded in the recommended invocation (iteration cap and
wall-clock as graph attributes or invocation parameters) — budget: N/A
alongside an emitted command is a contradiction the gate rejects.
caveats: line records the one-line disposition of anunresolved verifier objection (see the one-round cap below). It documents;
it never blocks.
the build anyway — adds one line quoting their exact words:
override: "<the user's own override words>". Note the tradeoff in one line
and proceed; pushback without those words never becomes an override.
A recorded override ENDS adjudication: ONE artifact rewrite, ONE gate
run, then proceed DIRECTLY to design — do NOT run the independent verifier
on an overridden verdict. The human has overruled the diagnosis; there is
nothing left to verify. (The honest trade: the override quote is the user's
own words quoted back in-session — the user is present to correct a misquote.)
When the verdict is recipe or one-shot, say so with a firm
recommendation, cite the one-sentence rule from
docs/PIPELINE_DESIGN_PRINCIPLES.md §0, and stop — the artifact is the record
of why, and these verdicts emit no pipeline invocation, so they end here,
outside the design gate. Do not follow a "no" with leading questions hunting
for a cycle ("want automatic retry on failure?") — a cycle you have to fish
for is not in the work, and assent to a question you posed can never be
quoted as evidence (rules above; the verifier checks exactly this).
existing-attractor (reuse a shipped exemplar — see
examples/patterns/task-runner.dot or
examples/pipelines/practical/bug-fix.dot) is not an exit: it hands the
user an invocation command, which is a design handover in every way that
matters. It carries the same artifact discipline (three questions with
quotes, counter: line, budget: line) and must pass the executed gate AND
clear independent verification below (its one round — or an override, which
skips it) before any command is emitted.
Before handing over ANYTHING actionable — a designed .dot, an
exemplar/existing-attractor recommendation, or ANY invocation command —
for any reason, including an override — run this check verbatim via bash:
d=".attractorify/diagnosis.md"; test -f "$d" \
&& [ "$(grep -Ec '^Q[123] \([a-z -]+\): (yes|no)( — derived \(user-delegated\): .+)?$' "$d")" -eq 3 ] \
&& [ "$(grep -Ec '^Q[123] quote: ".+"$' "$d")" -eq 3 ] \
&& ! grep -q 'NO EVIDENCE IN SESSION' "$d" \
&& ! grep -q 'PROVISIONAL' "$d" \
&& grep -Eq '^status: FINAL$' "$d" \
&& { grep -Eq '^verdict: (attractor|existing-attractor)$' "$d" || grep -Eq '^override: ".+"$' "$d"; } \
&& grep -Eq '^counter: ".+" — .+' "$d" \
&& grep -Eq '^budget: max [0-9]+ nodes; gates: .+' "$d" \
&& echo "DIAGNOSIS GATE: PASS — form ok; next: verify (or design directly on a recorded override)" \
|| { echo "DIAGNOSIS GATE: FAIL — no .dot, no invocation command; revise the diagnosis or ask"; false; }
The gate fails closed — this mirrors the engine's fail-closed goal-gates:
a defaulted, absent, provisional, or quote-free verdict never satisfies it.
On FAIL, produce no design; go back to the diagnosis or to clarifying
questions. Do not weaken the check to fit the artifact; fix the artifact, or
honestly stop. A PASS authorizes only the next step: this gate verifies
form, not truth — independent verification below is what authorizes design.
A bash gate cannot tell a real quote from a relevant one, and the judgment
that authors the evidence is the same judgment that folds — so certification
is taken away from the authoring judgment. Once the artifact is written and
the form gate passes — unless a valid override: line is recorded, which
ends adjudication (rule above): overridden verdicts skip this section
entirely — and BEFORE any handover (a designed .dot, an
existing-attractor recommendation, or any invocation command), you MUST
delegate verification to a fresh-context agent with no stake in the design:
use the same delegate tool as the expert consultation in Step 3, but NOT
attractor:attractor-expert — a plain clean-slate delegation, which sees
only what the instruction carries. That isolation is the point.
The verifier audits the diagnosis, not just the quotes: armed only with
quote-integrity questions, a coherent rationalization sails through — so the
instruction arms it with the doctrine's counter-tests and requires it to
re-derive the answers itself before looking at yours.
The delegation instruction must carry (a) the artifact content verbatim,
(b) the user's session turns, quoted verbatim, and (c) this ask:
You are verifying a diagnosis you did not write. Do not trust the
artifact's answers.
FIRST, re-derive the three-question answers YOURSELF from the user turns
alone, before reading the artifact's answers:
Q1 (cycle): does THIS work loop attempt -> machine-verify -> retry?
Q2 (evidence-gated exit): is the exit gated on a machine-checkable
check, external to the worker?
Q3 (bad-day survival): would it still land if any one LLM node had a
bad day?
Then compare your derivation with the artifact's answers. ANY mismatch
=> INVALID, and you must show your own derivation.
Apply these counter-test rules; each violation => INVALID:
- Recurrence of a task CATEGORY (releases happen again, reports happen
again) is NOT a convergence cycle. A cycle exists only if THIS work
loops attempt -> machine-verify -> retry.
- A human approval, review, or sign-off step makes the exit human-gated
— recipe-plane, not an attractor. Any machine proxy for the human's
satisfaction (marker files, format checks standing in for approval)
is manufactured evidence, not a gate.
- Desire, enthusiasm, schedule-pressure, and complaint quotes are never
evidence for ANY question.
- Q2 evidence must name a concrete machine check (a command or exit
condition) in the user's or the repo's own words.
If the artifact contains an `override: "..."` line, the override changes
the game. Check exactly two things: (a) the quoted words are verbatim
from a USER turn, and (b) they genuinely acknowledge the diagnosis
outcome AND direct the build anyway. The desire/enthusiasm exclusion
above does NOT apply to override quotes — an informed override IS a
directed desire; that is its nature. A valid override => VERIFIER: VALID
even when the three questions fail (that is the override's entire
purpose). An override quote that is not verbatim, or that expresses
desire without acknowledging the diagnosis => INVALID as before.
(This clause serves override-bearing artifacts that reach a verifier by
another path — the skill itself does not send overridden verdicts here.)
Then, for each of Q1/Q2/Q3, judge the quoted evidence:
1. Is the quote verbatim from a USER turn (not from the assistant's own
words, questions, or proposals)?
2. Is it genuine evidence FOR that specific question (not merely related
to the topic)?
3. Is it NOT assent to an option, menu, or checklist the assistant itself
proposed?
An answer clearly marked "derived (user-delegated)" with a stated basis,
whose quote line is the user's own deferral ("your call", "you decide"),
is acceptable evidence — judge the basis, not the absence of a user quote.
And: is the counter: line's disposition honest — a real rebuttal grounded
in user-originated evidence, or an honest concession?
Reply with exactly one of:
VERIFIER: VALID
VERIFIER: INVALID — <per-question reasons + your own derivation>
Verification is capped at ONE round per diagnosis — the cap bounds
worst-case latency by construction (a fresh-context judge re-litigates
everything each round, so unbounded rounds chase a moving target instead of
converging). On VERIFIER: VALID, proceed — to design, or to an
existing-attractor handover. On INVALID, revise the diagnosis ONCE,
honestly — which may flip the verdict to recipe or one-shot: that is a
legitimate outcome, not a failure — re-run the form gate, then PROCEED,
recording the objection's disposition in the artifact (the optional
caveats: line for anything left unresolved). Do not run the verifier
again and do not shop for a second opinion; further verifier objections are
never blockers. If the one revision cannot honestly resolve the objection,
convert it into ONE targeted user question (Step 2) instead of another
verifier round. The verifier exists to catch exactly two theater modes:
real-but-irrelevant quotes, and self-dealt evidence (assent to your own
proposals cited as the user's ask). A fold that survives independent
verification means the diagnosis discipline cannot be enforced in-skill at all.
Fallback (delegation unavailable): answer the three verifier questions in
a visibly separate self-check step before proceeding — weaker, because the
authoring judgment is certifying itself; say so in the handback.
When the user pushes back on a "no" without new information ("are you sure?",
"I'd really like a pipeline", "let's do it anyway"), hold: restate which
questions fail (a sentence each, not a doctrine wall), re-offer the
alternative, and ask one open question — what new constraint changes the
analysis? Ask it OPEN: do not propose candidate gates, checks, or menus
yourself — a menu invites assent, and assent to your own menu is not
evidence (the same anti-self-dealing rule as above). A reversal requires **rewriting .attractorify/diagnosis.md with
new user-originated evidence, then re-running the gate AND the verifier** (a
rewritten diagnosis with new evidence gets its own single round) —
social pressure produces no quotes, so an artifact that could not pass before
the pushback still cannot. A human approval/sign-off step is not a
machine-checkable gate: it belongs on the counter: line, not engineered
around. This skill is an adoption surface for the doctrine, not an
attractor-pushing machine.
Never one-shot a pipeline design from under-determined context. A .dot
generated from a guessed DoD, budget, or target repo is wrong-but-plausible at
the architecture level — no gate inside the pipeline can catch a sink that was
wrong before the first node ran. Designing from guesses on an under-determined
ask is the ask-first failure: a provisional diagnosis with questions is always
available and always preferred.
The three-gap checklist. On an under-determined ask, put targeted
clarifying questions to the user BEFORE any design artifact — covering
whichever of these gaps the session leaves genuinely open (gaps to cover, not
a script to recite; and this is the under-determined-ask path, distinct from
the single open question of the pushback path in Step 1):
mandatory whenever the workspace holds more than one candidate: never
guess between candidates, and never infer the target from repo state alone.
carved around: the observable end-state and the external,
out-of-worker-context check that confirms it.
a guess like any other.
Each answer must land machine-visibly in the deliverable. The chosen
target becomes a working directory / path / parameter in BOTH the pipeline's
deterministic gate commands AND the handed-over invocation — prose-only
scoping is not scoping: a verify command run from a parent directory sweeps
repos the user excluded. The DoD becomes the deterministic gate; the caps
become graph attributes or invocation parameters.
If the session already answers a gap, do not ask it again — a fixed intake
questionnaire remains the anti-pattern. An explicit deferral in reply ("your
call", "no strong opinion") ANSWERS the gap by delegation: derive and record
per Step 1's deferral rule — do not re-ask it. While questions are outstanding, the
artifact carries status: PROVISIONAL — which cannot pass the gate, so design
cannot start from it. **Re-diagnosis after answers is mechanical, not
optional:** rewrite .attractorify/diagnosis.md quoting the new answers (the
user's replies are now session evidence), set status: FINAL only when every
quote line is real, and re-run the gate. The PROVISIONAL marker clears only by
re-running the test against quotes — never by the passage of conversation.
Entry condition: the diagnosis gate above has returned PASS, and one of:
the independent verifier returned VERIFIER: VALID; a valid override:
line is recorded (adjudication ended — no verifier run); or the single
INVALID round was followed by one honest revision, a fresh gate PASS, and
the objection's disposition recorded (caveats: line if unresolved). Then:
budgets, evidence gates, target repo. These are the four walls of the basin.
attractor-expert agent — by delegation, not by reading itsfile.** Delegate to attractor:attractor-expert at design start (pattern and
shape choice), for any mid-build routing or engine-semantics question, and
again for a final review of the drafted .dot before handing it back. The
agent is loaded with engine semantics, DOT syntax, and the full authoring
guide; generic builders carry no attractor engine semantics. If delegation
is unavailable, fall back to reading agents/attractor-expert.md directly.
docs/PIPELINE_DESIGN_PRINCIPLES.md §0:name the sink first, build the gate, build the loop, only then add work nodes.
The node contract (Objective / Constraints / Available capabilities / Required
evidence) is documented in docs/DOT-AUTHORING-GUIDE.md §Philosophy.
(docs/PIPELINE_DESIGN_PRINCIPLES.md §0, control-plane vs recipe-plane
line) and keep the design inside the artifact's budget: line. Needing
more nodes is a diagnosis change, not a design flourish: revise the
artifact first — naming the evidence gate that justifies the extra
machinery — re-run the gate, and only then grow the graph.
.dot file to a named path inthe target repo (e.g. <task-id>.dot), then run:
bash -c "attractor lint <path>"
A .dot that fails attractor lint (TOPO-001 through TOPO-005, documented in
docs/DOT-AUTHORING-GUIDE.md) is not a runnable artifact. Fix lint findings
before handing back.
.dot file path, the exact invocation command, and aone-line summary of why each structural choice was made. The chosen target
must appear as a working directory / path / parameter in both the graph's
deterministic gate commands and the invocation, and both caps — iterations
AND wall-clock duration — must be machine-encoded in graph attributes or
invocation parameters; scoping or a budget stated only in prose is neither.
docs/PIPELINE_DESIGN_PRINCIPLES.md §0 — one-sentence rule, control-plane vsrecipe-plane line, three-question test, design order
docs/DOT-AUTHORING-GUIDE.md — node contract, DOT syntax, TOPO-001..005 lintrules, attractor lint CLI
attractor:attractor-expert — the consultable expert agent; delegate to itfor any pipeline design or debugging question (source prompt:
agents/attractor-expert.md; read directly only when delegation is unavailable)
examples/patterns/task-runner.dot — canonical control-plane skeletonexamples/pipelines/practical/bug-fix.dot — shipped exemplar for "use theexisting attractor" recommendations
If the user invokes /attractorify <description>, treat $ARGUMENTS as the
initial session context and apply the three-question test to it immediately.
If empty, read the current session context to identify the work before diagnosing.
a pipeline is the human's explicit call.
reproduce the doctrine inside its own body.
not answer; a fixed intake questionnaire is the anti-pattern this skill exists
to prevent one level up. (The diagnosis artifact is the skill's own verdict
record, written from session evidence — never a form posed to the user.)
Take microsoft/attractorify from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.