
Elicit
- 2.2k installs
- 442 repo stars
- Updated July 22, 2026
- juxt/allium
How to conduct structured discovery conversations that produce complete, unambiguous Allium specifications capturing what software does without prescribing how.
About
Elicit guides developers through building Allium specifications via conversation, surfacing ambiguities and producing executable domain specifications. The skill covers five phases: process discovery, scope definition, happy-path flow mapping, edge-case exploration, and refinement. It teaches techniques for finding the right abstraction level using the Why test, Could-it-be-different test, and Template-vs-Instance test. Principles include asking one question at a time, distinguishing product from implementation, surfacing ambiguity explicitly, and knowing when to defer detail to separate specs. The skill includes concrete patterns for scope documentation, configuration vs hardcoding decisions, and handling black-box logic.
- Five-phase elicitation methodology: process discovery, scope, happy path, edge cases, refinement
- Three core abstraction tests: Why, Could-it-be-different, Template-vs-Instance to eliminate implementation details
- Techniques for process discovery, detail elicitation, obstacle elicitation, and assumption checking
- Guidance on scope documentation, actor identification, and entity lifecycle mapping through conversation
- Traps to avoid: Obviously, Edge Case Spiral, Vague Agreement, Missing Actor, Equivalent Terms
Elicit by the numbers
- 2,241 all-time installs (skills.sh)
- +159 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #174 of 1,879 Documentation skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/juxt/allium --skill elicitAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.2k |
|---|---|
| repo stars | ★ 442 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 22, 2026 |
| Repository | juxt/allium ↗ |
What it does
Conduct structured discovery conversations to build Allium specifications from scratch, capturing domain behavior and requirements without prescribing implementation.
Who is it for?
Building new specifications from scratch; eliciting requirements from stakeholders; capturing domain behavior before implementation; discovering edge cases and failure paths; refining vague ideas into executable specific
Skip if: Quick feature requests; extracting specifications from existing code (use distill skill); minor updates to existing specs (use tend skill); verifying alignment between spec and implementation (use weed skill).
When should I use this skill?
User wants to create a specification from scratch; user describes a process and needs help shaping it; user names entities but has not articulated full lifecycle; user has vague idea needing structure; user has existing
What you get
A complete Allium specification with clear scope, documented entities, state transitions, rules, surfaces, and open questions ready for implementation or further detailed specification.
- Validated spec narratives
- Assumption check results
By the numbers
- Provides 4 assumption-checking techniques: show-back, ordering, scenario traces, and actor verification
Files
Elicitation
This skill guides you through building Allium specifications by conversation. The goal is to surface ambiguities and produce a specification that captures what the software does without prescribing implementation.
Scoping the specification
Before diving into details, establish what you are specifying. Not everything needs to be in one spec.
Questions to ask first
"What's the boundary of this specification?" A complete system? A single feature area? One service in a larger system? Be explicit about what is in and out of scope.
"Are there areas we should deliberately exclude?" Third-party integrations might be library specs. Legacy features might not be worth specifying. Some features might belong in separate specs.
"Is this a new system or does code already exist?" If code exists, you are doing distillation with elicitation. Existing code constrains what is realistic to specify.
Documenting scope decisions
Capture scope at the start of every spec:
-- allium: 3
-- interview-scheduling.allium
-- Scope: Interview scheduling for the hiring pipeline
-- Includes: Candidacy, Interview, Slot management, Invitations, Feedback
-- Excludes:
-- - Authentication (use oauth library spec)
-- - Payments (not applicable)
-- - Reporting dashboards (separate spec)
-- Dependencies: User entity defined in core.alliumThe version marker (-- allium: N) must be the first line of every .allium file. Use the current language version number.
Finding the right level of abstraction
Too concrete and you are specifying implementation. Too abstract and you are not saying anything useful.
The "Why" test
For every detail, ask: "Why does the stakeholder care about this?"
| Detail | Why? | Include? |
|---|---|---|
| "Users log in with Google OAuth" | They need to authenticate | Maybe not, "Users authenticate" might be sufficient |
| "We support Google and Microsoft OAuth" | Users choose their provider | Yes, the choice is domain-level |
| "Sessions expire after 24 hours" | Security/UX decision | Yes, affects user experience |
| "Sessions are stored in Redis" | Performance | No, implementation detail |
| "Passwords must be 12+ characters" | Security policy | Yes, affects users |
| "Passwords are hashed with bcrypt" | Security implementation | No, how not what |
The "Could it be different?" test
Ask: "Could this be implemented differently while still being the same system?"
- If yes, it is probably an implementation detail. Abstract it away.
- If no, it is probably domain-level. Include it.
Examples:
- "Notifications sent via Slack". Could be email, SMS, etc. Abstract to
Notification.created(channel: ...). - "Interviewers must confirm within 3 hours". This specific deadline matters at the domain level. Include the duration.
- "We use PostgreSQL". Could be any database. Do not include.
- "Data is retained for 7 years for compliance". Regulatory requirement. Include.
The "Template vs Instance" test
Is this a category of thing, or a specific instance?
| Instance (implementation) | Template (domain-level) |
|---|---|
| Google OAuth | Authentication provider |
| Slack | Notification channel |
| 15 minutes | Link expiry duration (configurable) |
| Greenhouse ATS | External candidate source |
Sometimes the instance IS the domain concern. "We specifically integrate with Salesforce" might be a competitive feature. "We support exactly these three OAuth providers" might be design scope.
When in doubt, ask the stakeholder: "If we changed this, would it be a different system or just a different implementation?"
Levels of abstraction
Too abstract: "Users can do things"
|
Product level: "Candidates can accept or decline interview invitations"
|
Too concrete: "Candidates click a button that POST to /api/invitations/:id/accept"Signs you are too abstract. The spec could describe almost any system. No testable assertions. Product owner says "but that doesn't capture..."
Signs you are too concrete. You are mentioning technologies, frameworks or APIs. You are describing UI elements (buttons, pages, forms). The implementation team says "why are you dictating how we build this?"
Configuration vs hardcoding
When you encounter a specific value (3 hours, 7 days, etc.), ask:
1. Is this value a design decision? Include it. 2. Might it vary per deployment or customer? Make it configurable. 3. Is it arbitrary? Consider whether to include it at all.
-- Hardcoded design decision
rule InvitationExpires {
when: invitation: Invitation.created_at + 7.days <= now
...
}
-- Configurable
config {
invitation_expiry: Duration = 7.days
}
rule InvitationExpires {
when: invitation: Invitation.created_at + config.invitation_expiry <= now
...
}Black boxes
Some logic is important but belongs at a different level:
-- Black box: we know it exists and what it considers, but not how
ensures: Suggestion.created(
interviewers: InterviewerMatching.suggest(
considering: {
role.required_skills,
Interviewer.skills,
Interviewer.availability,
Interviewer.recent_load
}
)
)The spec says there is a matching algorithm, that it considers these inputs and that it produces interviewer suggestions. The spec does not say how matching works, what weights are used or the specific algorithm.
This is the right level when the algorithm is complex and evolving, when product owners care about inputs and outputs rather than internals, and when a separate detailed spec could cover it if needed.
Reading the initial prompt
Before choosing an approach, assess what the user is bringing. The initial prompt tells you where to start.
The user describes a process. "We have a hiring pipeline where candidates apply, get screened, interview, then we decide." They're thinking at the process level. Start with process discovery — let them describe the flow, then help organise it into spec constructs. Consult process discovery.
The user names entities. "I need to spec an Order entity with states and transitions." They're already thinking at the construct level. Skip process discovery and move to scope definition, then fill in detail. Consult detail elicitation when working through rules and surfaces.
The user has a vague idea. "We need to build something for managing customer support." They need help shaping the idea before specifying it. Start with process discovery using open questions: "Tell me about what happens when a customer reaches out for help." Consult process discovery.
The user has existing code. "We have a payments service and I want to capture what it does." This is distillation with elicitation. Point them to the distill skill, or combine both: distill the structure from code, elicit the intent from the stakeholder.
The user has an existing spec. Read the spec first. Use assessing specs to determine what level of development each entity is at. Skip phases the spec has already covered — don't re-ask scope questions for a spec that already has scope comments, or re-discover processes for a spec that already has transition graphs. Start at the level each entity needs: detail elicitation for entities with lifecycles but no rules, obstacle elicitation for entities with rules but no failure paths.
Elicitation methodology
Phase 0: Process discovery
Goal: Understand the processes the system supports before identifying constructs.
Not every session needs this phase. If the user arrives with entities and lifecycles already in mind, skip to Phase 1. If they arrive with a process description or a vague idea, start here.
Let the user describe the system in their own words before imposing Allium structure. Capture the process, the actors, the outcomes, then organise into constructs. See process discovery for specific techniques.
Outputs: Process names and outcomes. Rough sequence of steps. Actors identified. Enough to write a coarse spec (entities with transition graphs and open questions).
Watch for: The urge to jump to entity definitions too early. Stay at the process level until the flow is clear.
Phase 1: Scope definition
Goal: Understand what we are specifying and where the boundaries are.
Questions to ask:
1. "What is this system fundamentally about? In one sentence?" 2. "Where does this system start and end? What's in scope vs out?" 3. "Who are the users? Are there different roles?" 4. "Are there existing systems this integrates with? What do they handle?"
If Phase 0 was skipped, also ask: "What are the key processes this system supports? What does success look like for each?" This anchors entity identification to processes rather than enumerating nouns in isolation. The techniques in process discovery apply here too — use past tense recall and outcome-first questioning if the user struggles to articulate the process.
Outputs: List of actors and roles. List of core entities (derived from the process if Phase 0 ran). Boundary decisions (what is external). One-sentence description.
Watch for: Scope creep ("and it also does X, Y, Z", gently refocus). Assumed knowledge ("obviously it handles auth", make explicit). Descriptions that suggest a library spec rather than application-specific logic (e.g. OAuth, payment processing, email delivery).
Phase 2: Happy path flow
Goal: Trace the main journey from start to finish.
If Phase 0 produced a walking skeleton (see process discovery), use it as the starting point. Otherwise, ask: "If we could only build one path through this process, what would it be?" Write the skeleton as a coarse spec and describe it back to the user in domain terms (see assessing specs).
Then flesh out: "What triggers each step? Who's involved? What changes?" Follow one entity through its lifecycle, capturing state transitions, actors and triggers.
Candidacy:
applied -> screening -> interviewing -> deciding -> hired | rejectedOutputs: Transition graphs for key entities. Main triggers and their outcomes. Actor assignments at each step.
Watch for: Jumping to edge cases too early ("but what if...", note it and stay on happy path). Implementation details creeping in ("the API endpoint...", redirect to outcomes).
After writing spec constructs, run allium check if the CLI is available. Fix structural issues before continuing — don't wait until Phase 4 to validate.
After establishing the skeleton, consult detail elicitation for techniques on filling in rules, surfaces, fields and data dependencies.
Phase 3: Edge cases and failure paths
Goal: Discover what can go wrong and how the system handles it.
Consult obstacle elicitation for techniques. The key approaches:
- Use the pre-mortem: "Imagine this system has been built and it's failing. What went wrong?"
- At each step: "What if nobody does anything here? After a day? A week?"
- At each handoff: "Who takes over? How do they know it's their turn? What do they need to see?"
- At each transition: "What if the preconditions aren't met? Can this be reversed?"
- For external dependencies: "How does this information enter the system? What if the external service is unavailable?"
Outputs: Exception transitions. Temporal triggers with requires guards. Escalation paths. Terminal error states. Invariants.
Watch for: Infinite loops ("then it retries, then retries again...", need terminal states). Missing escalation, because eventually a human needs to know.
When stakeholders state system-wide properties ("balance never goes negative", "no two interviews overlap for the same candidate"), these are candidates for top-level invariants. Capture them as invariant Name { expression } declarations.
After writing rules and exception transitions, run allium check if the CLI is available. Fix issues before moving to refinement.
Phase 4: Refinement
Goal: Verify and complete the specification.
Consult assumption checking for techniques. Describe what the spec says in domain terms and test it against the user's mental model. Trace concrete scenarios through the spec. Test ordering assumptions. Verify actor assignments.
If the Allium CLI is available, run allium check and use diagnostics to identify structural gaps. If allium analyse is available and the spec has rules and surfaces, run it and use findings to surface process-level gaps. Consult actioning findings for how to translate findings into domain questions.
Questions to ask:
1. "Looking at [entity], are these states complete? Can it be in any other state?" 2. "Is there anything we haven't covered?" 3. "This rule references [X], do we need to define that, or is it external?" 4. "Is this detail essential here, or should it live in a detailed spec?"
Technique: Take a concrete scenario and trace it through the spec. "Let's say Alice applies for the Senior Engineer role. Walk me through what happens to her candidacy."
Outputs: Complete entity definitions. Open questions documented. Deferred specifications identified. External boundaries confirmed.
When the same obligation pattern (e.g. a serialisation contract, a deterministic evaluation requirement) appears across multiple surfaces, suggest extracting it as a contract declaration for reuse.
Elicitation principles
Ask one question at a time
Bad: "What entities do you have, and what states can they be in, and who can modify them?"
Good: "What are the main things this system manages?" Then: "Let's take [Candidacy]. What states can it be in?" Then: "Who can change a candidacy's state?"
Work through implications
When a choice arises, do not just accept the first answer. Explore consequences.
"You said invitations expire after 48 hours. What happens then?" "And if the candidate still hasn't responded after we retry?" "What if they never respond, is this candidacy stuck forever?"
This surfaces decisions they have not made yet.
Distinguish product from implementation
When you hear implementation language, redirect:
| They say | You redirect |
|---|---|
| "The API returns a 404" | "So the user is informed it's not found?" |
| "We store it in Postgres" | "What information is captured?" |
| "The frontend shows a modal" | "The user is prompted to confirm?" |
| "We use a cron job" | "This happens on a schedule, how often?" |
Surface ambiguity explicitly
Better to record an open question than assume.
"I'm not sure whether declining should return the candidate to the pool or remove them entirely. Let me note that as an open question."
open question "When candidate declines, do they return to pool or exit?"Iterate willingly
It is normal to revise earlier decisions.
"Earlier we said all admins see all notifications. But now you're describing role-specific dashboards. Should we revisit that?"
Prioritise depth over breadth
Fully develop the most important entity first. Leave others coarse with open questions. The user can return to flesh them out in a later session. Trying to develop every entity to the same level in one conversation risks context exhaustion without completing anything.
Know when to stop
Not everything needs to be specified now.
"This is getting into how the matching algorithm works. Should we defer that to a detailed spec?"
"We've covered the main flow. The reporting dashboard sounds like a separate specification."
Common elicitation traps
The "Obviously" trap
When someone says "obviously" or "of course", probe. "You said obviously the admin approves. Is there ever a case where they don't need to? Could this be automated later?"
The "Edge Case Spiral" trap
Some people want to cover every edge case immediately. "Let's capture that as an open question and stay on the main flow for now. We'll come back to edge cases."
The "Vague Agreement" trap
Do not accept "yes" without specifics. "You said yes, candidates can reschedule. How many times? Is there a limit? What happens after that?"
The "Missing Actor" trap
Watch for actions without clear actors. "You said 'the slots are released'. Who or what releases them? Is it automatic, or does someone trigger it?"
The "Equivalent Terms" trap
When you hear two terms for the same concept, from different stakeholders, existing code or related specs, stop and resolve it before continuing.
"You said 'Purchase' but earlier we called this an 'Order'. Which term should we use?"
A comment noting that two terms are equivalent is not a resolution. It guarantees both will appear in the implementation. Pick one term, cross-reference related specs and update all references. Do not leave the old term anywhere, not even in "see also" notes.
Elicitation session structure
These timings apply to human-facilitated sessions. In an LLM conversation, use the phase outputs to decide when to advance rather than watching the clock.
Opening. Explain Allium briefly: "We're capturing what the software does, not how it's built." Agree on scope for this session.
Scope definition. Identify actors, entities, boundaries. Get the one-sentence description.
Happy path. Trace main flow start to finish. Capture states, triggers, outcomes.
Edge cases. Timeouts and deadlines. Failure modes. Escalation paths.
Wrap-up. Read back key decisions. List open questions. Name which entities are still coarse and what they need next. Identify next session scope if needed.
After elicitation
For targeted changes where you already know what you want, use the tend skill. For substantial additions that need structured discovery (new feature areas, complex entity relationships, unclear requirements), elicit is still the right tool even if a spec already exists. Checking alignment between specs and implementation belongs to the weed skill.
References
- Language reference, full Allium syntax
- Assessing specs, how to assess spec maturity and choose the right level of analysis
- Actioning findings, translating checker findings into domain questions
- Process discovery, techniques for when the user hasn't articulated the process yet
- Detail elicitation, techniques for filling in rules, surfaces and data dependencies
- Obstacle elicitation, techniques for exploring failure paths, timeouts and handoffs
- Assumption checking, techniques for verifying the spec matches the user's mental model
- Recognising library spec opportunities, signals, questions and decision framework for identifying library specs during elicitation
Assumption checking
Use these techniques when you have a coarse or complete spec and need to verify it matches the user's mental model. Show-back and ordering checks work on coarse specs (transition graphs without rules). Scenario traces require rules and surfaces to be defined. Actor verification works at any stage.
Show back what you've heard
After capturing a process or a set of rules, write the spec, then describe what it says in domain language. Don't present raw Allium syntax — translate constructs into a narrative the stakeholder can validate.
"Based on what you've described, here's the lifecycle for Candidacy. Applied, then screening, then interviewing, then deciding, and from there either hired or rejected. Screening can also lead directly to rejection. Is this right?"
Let the user correct, refine and extend. Common responses:
- "Yes, but you're missing X" → add the missing transition or entity
- "Not quite — Y happens before Z" → reorder the transitions
- "What about W?" → the user remembered something they hadn't mentioned
Test ordering assumptions
When the transition graph is taking shape, test whether the declared ordering is correct.
"Could these steps happen in a different order? What if the background check completed before screening was finished — would that change anything?"
This surfaces:
- False ordering constraints — steps the user assumed were sequential but could be parallel
- Missing concurrency — two things that can happen simultaneously but the graph forces them into sequence
- Hidden dependencies — steps that truly must follow a specific order, revealing data dependencies
If the user says "those could happen in either order", the transition graph may need restructuring. If they say "no, X absolutely must happen before Y", ask why — the answer is usually a data dependency that should be a requires clause.
Verify actor assignments
After identifying actors and their surfaces, check the assignments.
"I have the recruiter screening candidates and the hiring manager making the final decision. Is it always the hiring manager? Could a recruiter make the decision for junior roles?"
Actor boundaries are often assumed rather than decided. Testing them reveals:
- Role overlap — two actors who can do the same thing, needing explicit modelling
- Delegation — one actor acting on behalf of another
- Conditional assignment — different actors for different entity states or types
Check completeness at transition points
When moving from one entity to the next, or from happy path to edge cases, pause and check.
"Before we move on to interviews — looking at the screening flow, is there anything we haven't covered? Any situation that could come up that we haven't accounted for?"
Verify against real scenarios
Take a concrete scenario and trace it through the spec.
"Let's say Alice applies for the Senior Engineer role on Monday. Walk me through what happens to her candidacy using the spec we've written. Does each step match what you'd expect?"
If the spec produces a different outcome than the user expects, you've found a gap. The gap might be a missing rule, a wrong guard, or an unstated assumption.
Detail elicitation
Use these techniques when an entity has a lifecycle (transition graph) but needs rules, surfaces, fields and data dependencies filled in. The shape is known; the detail isn't.
Start from examples, not abstractions
Before writing rules, collect concrete scenarios. Ask for at least two specific cases.
"Give me a case where someone was hired. Now give me one where they were rejected at screening. What was different?"
The differences between the cases reveal the requires guards. The commonalities reveal the ensures outcomes. Rules emerge from comparing scenarios rather than being defined in the abstract.
When a rule is ambiguous or the user can't articulate the conditions, ask for more examples. "Can you give me a case where this went a different way?" Each new example narrows the rule.
Actor walkthrough
Pick a specific human actor and walk through their perspective in first person. For system actors (external APIs, background services), use third person instead: "The payment gateway receives a charge request. What does it need? What does it return?"
"You're the recruiter. You open the system on Monday morning. What's in front of you?" The answer is surface exposes — the data the actor sees.
"What can you do from here?" The answer is surface provides — the actions available.
"When would this action not be available?" The answer is the when guard on the provides clause.
"After you've done that, what happens next? Who takes over?" The answer reveals the handoff to the next actor and the next surface.
Trace data flow backward
When you encounter a decision point or a rule with preconditions, work backward from the requirement.
"The hiring manager needs to see interview feedback before deciding. Where does that feedback come from? Who provides it? At what point in the process?"
Each "where does this come from?" reveals a data dependency. Follow the chain until you reach a surface where an actor enters the data or an external system provides it. If the chain ends without a source, you've found a gap — a missing_producer in checker terms.
Ground abstract descriptions
When a user describes something abstractly ("the system shows relevant information"), ground it with a concrete question.
"If you were looking at the screen right now, what would you see? What specific information?" This surfaces the exact fields that need to be in exposes.
"Can you sketch what that screen looks like, in words? What's at the top? What's the main content?"
Prompt for external system boundaries
When a step depends on data from outside the system, ask how it enters.
"You mentioned the background check results come back. How does that happen? Does someone enter them manually, or does an external service send them automatically?"
The answer determines whether you need a surface facing a human actor or a contract integration point facing a system. Many process gaps involve external systems (payment processors, identity verification, notification services) where the spec needs an entry point but the user assumes the data just appears.
What to produce
If an entity's transition graph has grown beyond eight or so states, consider whether the lifecycle should be split. A booking entity that spans request, rental, inspection and deposit settlement might be clearer as separate entities linked by relationships. Ask the user: "This entity is covering a lot of ground. Would it be clearer to separate the [X] phase from the [Y] phase into its own entity?"
At the end of detail elicitation for an entity, you should have:
- Fields with types, including state-dependent fields (
whenclauses) - Rules witnessing every transition, with
requiresandensures - Surfaces for each actor that interacts with this entity, with
exposesandprovides - Relationships connecting this entity to related entities
- Config for any variable values (durations, thresholds, limits)
- Open questions for anything unresolved
Write the spec, then describe what it says in domain language and verify it with the user before moving on (see assumption checking).
Recognising library spec opportunities
During elicitation, stay alert for descriptions that suggest a library spec rather than application-specific logic. Library specs are standalone specifications for generic integrations that could be reused across projects.
This applies equally to distillation. When examining existing code and finding OAuth flows or payment processing, the same questions apply.
Signals that something might be a library spec
External system integration:
- "We use Google/Microsoft/GitHub for login"
- "Payments go through Stripe/PayPal"
- "We send emails via SendGrid/Postmark"
- "Calendar invites sync with Google Calendar"
- "We store files in S3/GCS"
Generic patterns being described:
- OAuth flows, session management, token refresh
- Payment processing, subscriptions, invoicing
- Email delivery, bounce handling, unsubscribes
- File upload, virus scanning, thumbnail generation
- Webhook receipt, retry logic, signature verification
Implementation-agnostic descriptions:
- "Users log in with their work account" (could be any SSO provider)
- "We charge them monthly" (could be any payment processor)
- "They get notified" (could be any notification infrastructure)
Questions to ask
When you detect a potential library spec, pause and explore:
1. "Is this specific to your system, or is it a standard integration?" If standard, it is likely a library spec candidate.
2. "Would another system integrating with [X] work the same way?" If yes, it is definitely a library spec candidate.
3. "Do you have specific customisations to how [X] works, or is it standard?" Standard behaviour points to a library spec. Heavy customisation might still be a library spec with configuration.
4. "Should we look for an existing library spec for [X], or do you need something custom?" This encourages reuse and saves effort.
How to handle the decision
Option 1: Use an existing library spec
"It sounds like you're describing a standard OAuth flow. There's likely an existing library spec for this. Shall we reference that rather than specifying the OAuth details here? Your application spec would just respond to authentication events."
Option 2: Create a new library spec
"The way you're describing this Greenhouse ATS integration sounds generic enough that it could be its own library spec. Other hiring applications might integrate with Greenhouse the same way. Should we create a separate greenhouse-ats.allium spec that this application references?"
Option 3: Keep it inline (rare)
"This integration is so specific to your system that it probably doesn't make sense as a standalone spec. Let's include it directly."
Common library spec candidates
| Domain | Likely library specs |
|---|---|
| Authentication | OAuth providers (Google, Microsoft, GitHub), SAML, magic links |
| Payments | Stripe, PayPal, subscription billing, usage-based billing |
| Communications | Email delivery, SMS, push notifications, Slack/Teams |
| Storage | S3-compatible storage, file scanning, image processing |
| Calendar | Google Calendar, Outlook, iCal feeds |
| CRM/ATS | Salesforce, HubSpot, Greenhouse, Lever |
| Analytics | Segment, Mixpanel, event tracking |
| Infrastructure | Webhook handling, rate limiting, audit logging |
The boundary question
When you identify a library spec candidate, the key question is: "Where does the library spec end and the application spec begin?"
The library spec handles:
- The mechanics of the integration (OAuth flow, payment processing)
- Events that any consumer would care about (login succeeded, payment failed)
- Configuration that varies between deployments
The application spec handles:
- What happens in your system when those events occur
- Application-specific entities (your User, your Subscription)
- Business rules unique to your domain
Example boundary:
-- Library spec (oauth.allium) handles:
-- - Provider configuration
-- - Token exchange
-- - Session lifecycle
-- - Emits: AuthenticationSucceeded, SessionExpired, etc.
-- Application spec handles:
-- - Creating your User entity on first login
-- - What roles/permissions new users get
-- - Blocking suspended users from logging in
-- - Audit logging specific to your compliance needsRed flags you missed a library spec
During review, watch for:
- Detailed protocol descriptions. "First we redirect to Google, then they redirect back with a code, then we exchange it for a token..." This is OAuth. Use a library spec.
- Vendor-specific details. "Stripe sends a webhook with event type
invoice.paid..." This is Stripe integration. Use a library spec. - Repeated patterns. If you are specifying similar retry/timeout/error handling for multiple integrations, extract a common pattern.
Obstacle elicitation
Use these techniques when exploring failure paths, timeouts, exception transitions and actor handoffs.
Use the pre-mortem
Instead of the abstract "what can go wrong?", use a concrete framing.
"Imagine it's six months from now. This system has been built and deployed. Something has gone wrong and people are frustrated. What happened?"
People are better at imagining concrete failure than listing abstract risks. The pre-mortem produces vivid, specific failure modes rather than generic edge cases. Each failure mode maps to an exception transition, a timeout rule, or an invariant.
Follow up each failure with: "How should the system have prevented that? Or handled it?" The answer is the rule or guard that's missing from the spec.
Ask what happens when nothing happens
At every step where a human actor needs to act, ask: "What if nobody does anything? After a day? After a week?"
The answer is one of:
- "Nothing, it just waits." This is a design decision worth making explicit. Document it as the intended behaviour, possibly with an open question about whether it's acceptable.
- "After X time, Y happens." This is a temporal trigger:
when: entity.timestamp_field + config.duration <= nowwithrequires: entity.status = expected_stateto prevent re-firing. Do not usebecomesfor time-delayed behaviour —becomesfires immediately when an entity enters a state, not after a delay. - "Someone should be notified." This surfaces a notification or escalation path.
Most specs underspecify inaction. The happy path assumes everyone acts promptly. Real systems have stale candidacies, expired invitations and abandoned carts. These need rules.
Explore handoffs between actors
At every state transition, ask: "Who takes over at this point? How do they know it's their turn? What do they need to see?"
The answers reveal:
- Actor transitions — which actor is responsible for the next step
- Notification needs — how the next actor learns they need to act
- Information requirements — what the next actor's surface must expose
- Related surface links — how surfaces connect to each other
Handoffs are where processes break in practice. The outgoing actor assumes the incoming actor knows what happened. The incoming actor assumes they'll be told. The spec needs to make the handoff explicit: what triggers the notification, what information it carries, and what the next actor sees when they arrive.
Enumerate alternatives at each step
For each step in the happy path, systematically ask: "What else could happen here?" Keep asking until the user can't think of anything more. This is the discipline that prevents gaps: stories and informal descriptions only capture the paths someone happens to think of. Enumeration forces completeness.
Work through the happy path step by step: 1. State the step: "At this point, the recruiter reviews the application." 2. Ask: "What's the main thing that happens?" (The happy path outcome — already captured.) 3. Ask: "What else could happen?" (First alternative — maybe rejection.) 4. Ask: "Anything else?" (Second alternative — maybe deferral, or requesting more information.) 5. Keep asking until exhausted. 6. For each alternative: "What happens next if this path is taken?" (Follow the alternative to its terminal state.)
Each alternative becomes either an exception transition in the graph, an additional rule, or an open question if the user isn't sure. If an alternative branches into its own multi-step flow, capture it as an open question and return to it in a later pass rather than following every branch immediately.
Systematically test each transition
After enumeration, test each transition for robustness:
- "What if the preconditions aren't met? What should happen?"
- "Can this transition be reversed? Can someone undo it?"
- "Is there a time limit on being in this state?"
- "Can this transition happen more than once?"
For critical entities, test every transition. For less critical entities, focus on the transitions most likely to fail or stall. Critical entities are those central to the system's value proposition, those that handle money or compliance-sensitive data, or those the user mentioned during the pre-mortem. Transitions most likely to stall are those that depend on external actors or systems, those with temporal dependencies, and those where a human must act.
What to capture
Obstacle elicitation produces:
- Exception transitions (screening → rejected, interview → cancelled)
- Temporal triggers with
requiresguards (invitation expires after 48 hours) - Escalation paths (stuck candidacy → notify recruiter after 5 days)
- Terminal error states (background check flagged → candidacy terminated)
- Invariants (system-wide properties that must hold: "no candidate can have two active candidacies for the same role")
- Open questions for unresolved failure scenarios
Process discovery
Use these techniques when the user hasn't articulated the process yet, when they're starting from scratch, or when you need to understand the shape of a system before getting into construct-level detail.
Let the user talk first
Before imposing any Allium structure, let the user describe the process in their own words. Don't interrupt for entity types, field names or state transitions. Capture the raw description, then organise it into constructs afterward. If the description becomes unclear or contradictory, ask a brief clarifying question, but don't redirect into Allium constructs yet.
Prompt with: "Tell me about this system. What does it do?" or "Walk me through the main thing that happens, start to finish."
Use past tense
When the user struggles to articulate a process in the abstract, switch to past tense. Recalling what happened is easier than prescribing what should happen.
"Tell me about the last time someone was hired at your company" produces richer material than "describe the hiring process." Follow up with "and then what happened?" to walk the timeline. The events become rule triggers, the actors become actors, the decisions become guards.
Start from outcomes
Most people can name what they're trying to achieve before they can describe how they get there. Ask about the destination before asking about the route.
"What does success look like for this process?" or "When this process finishes well, what's the result?" The answer gives you the terminal states. Then work backward: "What has to happen before that? And before that?"
If there are multiple outcomes (hired vs rejected, fulfilled vs refunded), capture them all. They define the shape of the transition graph.
Find the walking skeleton
Once you have a rough sense of the process, ask: "If we could only build one path through this, what would it be? The simplest journey from start to finish."
The answer is the happy path — the coarse spec. Entities with transition graphs showing the main flow. Everything else (exception paths, alternative flows, edge cases) is added incrementally.
Once you have the skeleton, write it as a coarse Allium spec (entities with transition graphs, actors, open questions) and describe it back to the user in domain language for validation — don't present raw syntax. The skeleton is the transition from free-form discovery to formalisation.
Identify actors early
Ask "who's involved?" early in the conversation. For each actor: "What do they need to do their job?" and "What do they need to see?"
Each actor's perspective is a partial view of the process. The full process emerges from composing these views. If two actors describe the same step differently, you've found either an ambiguity or a handoff that needs clarifying.
Layered decomposition
For complex processes, work through layers in order. Each layer surfaces a different kind of Allium construct. Ask about each layer before moving to the next.
1. Events. "What are the things that happen in this process?" Capture in past tense ("candidate applied", "background check completed", "offer accepted"). These become entity state transitions and rule triggers. 2. Commands. "For each event, what triggered it? A person doing something, or the system reacting?" Commands from people become surface provides actions. System reactions become rules with becomes or transitions_to triggers. 3. Actors. "Who issued each command? Which role or system?" Each distinct role or system becomes an actor declaration. 4. Entities. "Which thing in the system changed when this event happened?" Group events by the entity they affect. Each group becomes an entity with a lifecycle. 5. Policies. "Are there any automatic reactions — whenever X happens, Y should follow?" These become rules with chained triggers or becomes triggers. 6. Information needs. "At each decision point, what did the actor need to see to make the decision?" These become surface exposes and reveal data dependencies between entities. 7. Unknowns. "Is there anything here you're not sure about, or where different people would give different answers?" These become open_questions.
This layered approach produces a richer set of constructs than open-ended conversation. Use it when the process involves multiple actors, crosses entity boundaries, or when the user gives detailed but unstructured descriptions that need organising. For processes with a single actor and a straightforward lifecycle, the techniques above (outcomes-first, walking skeleton) are sufficient.
What to capture
Whether using layered decomposition or open-ended discovery, note:
- Events (things that happen) → entity state transitions, rule triggers
- Actors (people or systems involved) → actor declarations
- Decisions (choices someone makes) → rule guards, alternative transitions
- Information needs ("they need to see X to decide") → surface exposes, data dependencies
- Outcomes (what success and failure look like) → terminal states
- Unknowns ("I'm not sure how that works") → open questions
Before finding the walking skeleton, capture as prose notes or simple bullet lists ("Candidate applied → recruiter screened → interviews happened → decision made"). Don't use Allium syntax yet. After the skeleton is clear, organise into Allium constructs and describe the result back to the user in domain terms for correction.
When to stop
Process discovery is complete when you can write the walking skeleton: you know the main entities, their lifecycle states, the actors involved and the terminal outcomes. You don't need every detail — that's what later phases provide. If you have enough to write a coarse spec with transition graphs and open questions, move on.
Related skills
How it compares
Pick elicit over generic requirements templates when an Allium process spec needs structured show-back and scenario validation before implementation.
FAQ
Which validation techniques does elicit provide?
elicit provides four assumption-checking techniques: show-back narratives, ordering checks on transition graphs, scenario traces requiring defined rules, and actor verification usable at any specification stage.
Does elicit present raw Allium syntax to stakeholders?
elicit instructs agents to translate Allium constructs into domain-language narratives during show-back rather than presenting raw Allium syntax, so stakeholders can validate lifecycles and transitions in familiar terms.
Is Elicit safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.