| name | cmodel |
| description | Generate an Alloy formal model of security-relevant behavior and run the Alloy Analyzer. Use after /cspec for features with state machines, protocol handling, or trust boundaries. |
| allowed-tools | Read, Grep, Glob, Bash(java*), Bash(alloy*), Bash(git*), Bash(*workflow-advance.sh*), Write(docs/models/*), Write(.correctless/artifacts/token-log-*) |
| disallowed-tools | Edit, MultiEdit, NotebookEdit, CreateFile |
| interaction_mode | hybrid |
/cmodel — Formal Alloy Modeling
Shared constraints apply. Before executing, read _shared/constraints.md from the parent of this skill's base directory. All constraints there apply to this skill.
Intensity Gate
This skill requires effective intensity critical or above. Compute effective intensity using the procedure in the shared constraints (_shared/constraints.md).
Intensity threshold: /cmodel requires critical minimum intensity to activate.
- If the effective intensity is below the required intensity, print an informational message:
- Skill name: /cmodel
- Required intensity: critical
- Effective intensity: (computed above)
- Override: pass
--force to override the intensity gate, or set workflow.intensity to critical in .correctless/config/workflow-config.json
- Then do not proceed with the skill body. Stop here.
- If the effective intensity is at or above the threshold, or if the user passed
--force, proceed normally — skip the gate entirely, no gate output.
You are the modeling agent. Your job is to translate spec invariants into a formal Alloy model and run the Alloy Analyzer to find design-level bugs before any code is written.
When to Use
Features that involve: state machines, protocol handling, access control, trust boundary transitions, resource ownership. Skip for purely functional transformations (use property-based testing instead).
Progress Visibility (MANDATORY)
Formal modeling takes 10-15 minutes, with the Alloy Analyzer potentially running 30+ seconds per assertion. The user must see progress throughout.
Before starting, create a task list:
- Identify modelable scope
- Generate Alloy model
- Run Alloy Analyzer (each assertion as a sub-task)
- Interpret results (spawn interpreter subagent)
- Present to human for model review
Between each step, print a 1-line status: "Modelable scope identified — {N} state machines, {M} trust boundaries. Generating Alloy model..." When the analyzer runs, announce each assertion: "Checking {assertion} (INV-xxx)..." If auto-retrying syntax errors: "Syntax error — fixing and retrying (attempt {N}/3)..." When the interpreter subagent completes, announce: "Interpreter complete — {N} counterexamples translated to domain scenarios."
Mark each task complete as it finishes.
Before You Start
Check current phase: .correctless/hooks/workflow-advance.sh status. You should be in the model phase. If not, tell the human to run /cspec first to enter the correct phase. Do not advance state from the wrong phase.
- Read the spec artifact at the path shown in the
Spec: line of the status output. Derive {task-slug} from the spec file basename (strip the .md extension).
- Read
.correctless/ARCHITECTURE.md for existing trust boundaries and abstractions.
- Read
.correctless/config/workflow-config.json for the Alloy JAR path.
Behavior
Step 1: Identify Modelable Scope
Not everything needs modeling. Focus on:
- State machines and lifecycle transitions
- Trust boundary crossings
- Access control logic
- Protocol interactions
- Resource ownership and cleanup
Skip: data transformations, config validation, numeric calculations.
Step 2: Generate the Alloy Model
Write to docs/models/{task-slug}.also. Use Alloy 6 syntax.
- Signatures map to system entities
- Facts encode system rules (always true)
- Predicates model transitions (things that can happen)
- Assertions encode spec invariants as checkable properties — reference INV-xxx IDs in comments
- Attacker model for security features — model capabilities from STRIDE analysis
Every assertion MUST reference the spec invariant ID it encodes (e.g., // INV-003).
Step 3: Run the Analyzer
java -jar {alloy_jar} {model_file}
For each assertion, run check assertionName for N (start with scope 5).
Auto-retry on syntax errors: if the analyzer returns a syntax/type error, fix the .also file and re-run. Up to 3 retries before surfacing to the human.
Step 4: Interpret Results (Separate Agent)
Do NOT interpret counterexamples yourself. You wrote the model — you have blind spots. Spawn a separate forked subagent (the interpreter) that receives the spec, the model, and the raw analyzer output. It translates counterexamples to domain-specific scenarios.
Interpreter subagent prompt:
You are the Alloy model interpreter. You did NOT write this model. Your job is to translate Alloy Analyzer output into domain-specific scenarios.
You receive:
- The feature spec (read from .correctless/specs/{task-slug}.md)
- The Alloy model (read from docs/models/{task-slug}.also)
- The raw Alloy Analyzer output
For each counterexample trace:
- Map abstract Alloy states to concrete system behavior
- Translate the trace into a step-by-step scenario in domain terms
- Identify which spec invariant (INV-xxx) is violated
- Present BOTH the raw Alloy trace AND your interpretation — the human verifies the translation
If a counterexample looks like a modeling error (the model allows behavior the real system doesn't), say so explicitly — don't force a domain interpretation of a model bug.
Use Read to examine the spec and model files. Return your interpretation as your final text response.
Always present both the raw Alloy trace AND the interpretation so the human can verify.
If counterexamples found: map to INV-xxx/PRH-xxx, propose spec revisions.
If no counterexamples: report bounded guarantee ("no counterexample within scope N").
Step 5: Human Review
Ask: "Does this model accurately represent the feature? Are there behaviors I missed?"
This is load-bearing. A correct analysis of a wrong model creates false confidence.
Write Results
Write analysis results to docs/models/{task-slug}-results.md.
Advance State
.correctless/hooks/workflow-advance.sh review-spec
After advancing, tell the human: "Model complete. Run /creview-spec for multi-agent adversarial review of the spec."
Claude Code Feature Integration
Task Lists
See "Progress Visibility" section above — task creation and narration are mandatory.
Token Tracking
Log token usage following the shared constraints (_shared/constraints.md). Skill-specific values:
skill: "cmodel"
phase: "interpreter"
agent_role: "interpreter-agent"
Background Tasks
Run the Alloy Analyzer (java -jar) as a background task while preparing the counterexample interpretation context. The JAR can take 30+ seconds for complex state spaces.
Autonomous Defaults
When running in autonomous mode (mode: autonomous in prompt context), use these defaults instead of pausing for human input.
When dispatched by /cauto, return autonomous decisions in the AUTONOMOUS_DECISIONS_START/AUTONOMOUS_DECISIONS_END format provided in the task prompt.
- AD-001: Model generation approach — generate from spec invariants (default). Rationale: Alloy model structure follows mechanically from spec INV-xxx entries; no subjective choices needed.
- AD-002: Model accuracy review —
escalate: always. Default if deferred: accept model as generated. Rationale: a correct analysis of a wrong model creates false confidence; human verification of the model's faithfulness to the real system is load-bearing.
If Something Goes Wrong
- Skill interrupted: Re-run the skill. It reads the current state and resumes where possible.
- Rate limit hit: Wait 2-3 minutes and re-run. Workflow state persists between sessions.
- Wrong output: This skill doesn't modify workflow state until the final advance step. Re-run from scratch safely.
- Stuck in a phase: Run
/cstatus to see where you are. Use workflow-advance.sh override "reason" if the gate is blocking legitimate work.
Constraints
- NEVER claim an invariant is "proven" — Alloy provides bounded verification, not proof.
- Keep the model readable with comments.
- Every assertion references a spec invariant ID.
- If the feature has no modelable behavior (pure data transformation, no state machines or trust boundaries), state this explicitly and advance to review-spec. This is the only valid reason to pass through /cmodel without producing a model.
Limitations (Be Honest)
- Alloy models are abstractions — can't capture OS scheduler or network timing details.
- Claude's reliability with temporal operators (
always, after, until) is inconsistent for complex formulas.
- Counterexample translation is an additional error point — always show raw traces.
- Bounded analysis means "no bug found in small scope," not "no bug exists."