Project to spec
Skill itential/builder-skills/.claude/skills/project-to-spec
Use this skill when a user names a specific existing Itential project and wants it documented — reverse-engineered into a requirements spec and solution design. Trigger it for phrases like "document the DNS_Management project", "create a spec from the Firewall_Rule_Lifecycle project", "reverse-engineer project X into a spec", "I have a project with no docs — produce a customer-spec and solution design for it", or "use this project as a baseline for a rebuild". Reads the project's workflows, templates, and MOP components, infers business purpose and design decisions, and produces customer-spec.md + solution-design.md. For documenting global/unprojectized assets across the whole platform, use /documentation instead.From its SKILL.md
npx -y skills add itential/builder-skills --skill project-to-specAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
11.7 KB, as published. Nobody here has run it
Project to Spec
Purpose: Read an existing project → produce documentation
Output: customer-spec.md (inferred HLD) + solution-design.md (as-built LLD)
Feeds into: Can be handed directly to /solution-arch-agent (design-only mode) or /spec-agent for refinement
What This Does
Takes an undocumented or partially-documented project and produces the spec and design documents that should have existed before it was built. The engineer reviews and corrects the inferred documents — then they can feed into the standard delivery lifecycle for updates, rebuilds, or knowledge transfer.
Existing Project
│
├── Pull all components (workflows, templates, MOP)
├── Read each workflow: tasks, adapters, transitions, data flows
├── Infer: business purpose, phases, inputs, outputs, integrations
│
├── customer-spec.md ← inferred HLD (engineer reviews + corrects)
└── solution-design.md ← as-built LLD (actual component inventory)
Step 1: Identify the Project
Ask the engineer for a project name or ID. Then pull the project:
GET /automation-studio/projects/{projectId}
Or search by name:
GET /automation-studio/projects?contains=name:{projectName}
Response: {message, data: {_id, name, components: [...], members: [...]}}
Save the project ID and component list.
If the project is not returned
Project list/get responses are RBAC-filtered. A 404 or empty data array does NOT prove the project doesn't exist — it may be invisible to the calling client.
Important: Itential projects use per-project ACLs only. There is no platform-wide admin or "all-projects" role — every project explicitly grants access to specific users or groups via its own ACL. The calling client sees a project iff that project's ACL includes the client or one of its groups. (This applies to projects specifically; global Automation Studio assets that live outside any project are not access-restricted the same way.)
Before declaring the project missing, do all of:
- Identify the calling client —
GET /iam/clients/{client_id}(theclient_idfrom.auth.jsonor the env file). Note its group memberships — these (together with the client itself) determine which project ACLs it might be on. - Try a broader query —
GET /automation-studio/projects?limit=500and inspect the result for partial-name matches; thecontainsfilter is case-sensitive in some Platform versions. - Surface visibility, not absence — report: "No project named
{name}is visible to this client ({client_id}). It may not exist, or it may be access-restricted. To confirm, ask the project's owner (or someone with manage rights on that project) to add{client_id}to its ACL via the Automation Studio UI." - Do not auto-grant access. Adding the calling client to a project ACL is a privileged write to a shared resource — always ask the engineer to handle it via the UI, or via a different client that is already on that project's ACL with manage rights. If the engineer authorizes a DB-level read-only confirmation (e.g. local dev Mongo), that is acceptable, but the granting itself stays a human action.
Stop and wait for engineer direction before proceeding to Step 2.
Step 2: Pull All Components
For each component in the project, fetch the full document.
Workflows:
GET /automation-studio/workflows/detailed/{urlEncodedName}
Templates:
GET /automation-studio/templates/{id}
MOP Command Templates:
GET /mop/listATemplate/{name}
For each workflow, extract and save locally:
tasks— every task with name, app, adapter, incoming/outgoing variablestransitions— the flow between tasksinputSchema/outputSchema— what the workflow accepts and returns- Task summaries and descriptions (these often contain intent)
Save to {use-case}/project-components.json.
Step 3: Analyze the Components
Work through the components to reconstruct intent and structure.
Identify the orchestrator
Find the parent workflow — usually the one that:
- Has no
childJobreferences pointing to it from other workflows - References other workflows via
childJobtasks - Has the most complex transition graph
Map the data flow
For the orchestrator and each child:
- What are the inputs? (inputSchema properties)
- What adapters are called? (location: "Adapter" tasks)
- What utility tasks are used? (merge, query, evaluation, childJob, makeData)
- What are the outputs? (outputSchema properties, $var.job.x assignments)
- What external systems are touched? (adapter names → infer ServiceNow, Route53, etc.)
Infer the phases
Each major section of the orchestrator maps to a phase:
- A
childJobto a child workflow = one phase - An
evaluationbranch = a decision point - An adapter call cluster = an integration phase
- A
ViewData= an approval gate - Error handling branches = rollback/recovery phases
Reconstruct acceptance criteria
From the workflow structure, infer what "done" looks like:
- What does the final outgoing variable represent?
- What adapters were called? → "ServiceNow ticket created and updated"
- What verifications exist? →
evaluationtasks checking status - What is the
outputSchema? → these are the observable outcomes
Step 4: Produce customer-spec.md
Write the inferred HLD. Use the standard spec structure but mark inferred sections clearly.
# Use Case: {Inferred Name}
> **Note:** This spec was produced by reading project `{projectName}` ({projectId}).
> Review and correct any inferences before using as a delivery baseline.
## 1. Problem Statement
{Inferred from workflow descriptions, adapter usage, and task summaries}
## 2. High-Level Flow
{Inferred from orchestrator transition graph}
## 3. Phases
{One section per major workflow / childJob cluster}
## 4. Key Design Decisions
{Inferred from adapter choices, error handling patterns, approval gates}
## 5. Scope
**In scope (as built):** {list components that exist}
**Not observed:** {common patterns not present — rollback, notifications, etc.}
## 6. Risks & Mitigations
{Inferred from error transitions, evaluation branches}
## 7. Requirements
### Capabilities
{Derived from apps and tasks used}
### Integrations
{Derived from adapter names and instance IDs}
## 8. Batch Strategy
{Inferred from childJob loopType usage}
## 9. Acceptance Criteria
{Inferred from outputSchema and evaluation checks}
Step 5: Produce solution-design.md
Write the as-built LLD — this is factual, not inferred.
# Solution Design: {Project Name}
> **As-Built** — produced by reading project `{projectId}`.
## A. Environment Summary
{Platform, adapters found, apps used}
## B. Component Inventory
| # | Component | Type | Workflow/Template Name | ID |
|---|-----------|------|----------------------|-----|
| 1 | {name} | {workflow/template/mop} | {actual name} | {id} |
...
## C. Adapter Mappings
| Adapter | app name | adapter_id | Tasks Used |
|---------|----------|-----------|------------|
| ServiceNow | Servicenow | ServiceNow | createChangeRequest, updateChangeRequest |
...
## D. Workflow Structure
For each workflow: inputs, task sequence, outputs, error handling pattern.
## E. Data Flow
Key variables and how they move between tasks and workflows.
## F. Known Gaps
Patterns not present that are typically expected:
- No rollback logic observed
- No notifications (email/Teams)
- No audit trail
etc.
Step 6: Write Memory File
Before presenting to the engineer, create {use-case}/use-case-memory.md from ${CLAUDE_PLUGIN_ROOT}/helpers/use-case-memory.md and populate it with what you just read — don't leave this for later:
- Platform References — platform URL, project name, project
_id, adapter instance names and type names, group memberships observed - What Was Built — every component from the inventory table: name, type, ID, status=
existing - Architecture Decisions — any patterns you inferred (why childJob loop, why this adapter, why approval gate)
- Stage / Status —
Stage: delivered,Status: activeif the project is fully in production and this is pure documentation;Stage: requirements(or wherever the engineer decides to re-enter) if this is a baseline for a rebuild or refinement
This means any skill that picks up from here (spec-agent, solution-arch-agent, builder-agent, qa-agent) starts with the real IDs already recorded — no re-discovery.
Step 7: Present to Engineer
Show both documents and walk through:
- Inferences to verify — "I inferred the purpose is X based on the adapter usage and task names. Is that correct?"
- Gaps — "I don't see rollback logic or notifications. Were these intentional omissions or should they be added?"
- Next steps — offer three options:
- Use as-is — accept the documents as the baseline for this project
- Refine the spec — hand to
/spec-agentto refine the requirements with the engineer - Redesign — hand to
/solution-arch-agentin design-only mode to produce an updated implementation plan
What to Watch For
Orphaned tasks: Tasks with no useful summary — check their adapter/app and incoming variables to infer purpose.
Non-hex task IDs: If you encounter task IDs like apush or myTask, note them — these are a known bug pattern ($var references silently fail on these).
Deep nesting: childJob → childJob → childJob patterns indicate a modular design — document each layer separately.
Static values as indicators: Hard-coded strings in merge tasks or newVariable tasks often reveal business rules (e.g., "value": "production" → production-only path).
Missing error transitions: Note any adapter tasks without error transitions — this is a quality gap in the existing implementation.
Gotchas
- Workflow names include
@projectId:prefix — strip it when displaying to the engineer GET /automation-studio/workflows?exclude-project-members=falseis needed to list project-owned workflows- Template
datafield is a JSON string, not an object — parse it before analyzing - childJob
workflowfield shows the child workflow name (with prefix) — this is the dependency graph - Task descriptions and summaries are the best source of intent — use them heavily
- Project not returned ≠ project doesn't exist. Itential projects use per-project ACLs only — there is no platform-wide admin role that sees every project. List/get responses are filtered by the calling client's ACL membership per project. A named project the engineer expects but the API doesn't return is more likely access-restricted than missing. Follow the "If the project is not returned" path in Step 1 — never silently switch to a different project, never declare absence without surfacing the visibility caveat, and never grant the calling client access on its own initiative.