Your first scaffold — from empty directory to working substrate
What you need: project-state installed as a Claude Code plugin.
Scaffolding creates the project-state/ directory that every other skill reads from and writes to. The scaffolder is a 6-step wizard. It runs once per project. The output is a correctly-shaped substrate — manifest, reporting matrix, phase configuration, activity log, and empty entity directories — so that 29 other skills can operate without further setup.
Navigate to the root of your project's shared drive folder (or any empty directory), open Claude Code, and run:
/project-scaffolder
Step 1 — Pack selection
The scaffolder presents all available compliance packs. On Coworker (claude.ai), this renders as an HTML artifact with clickable OptionCard components. In Claude Code (CLI), it's a numbered list.
Either way, the information is the same:
1. agile-default [starter] — Scrum/Kanban, no external funder
2. board-investor [starter] — Startup with board reporting
3. client-services [starter] — Client engagement, QBR cadence
4. open-source-community [starter] — Community-governed OSS project
5. sred-canada [starter] — Canadian SR&ED tax credit claims
6. grant-canada [starter] — Canadian grant submission (19 programs)
7. pic-pcais [production] — Protein Industries Canada PCAIS
Pick the pack that matches your project type. The [production] badge means the pack has been used on real projects with real auditors. [starter] means the structure is complete but hasn't been battle-tested yet.
You can load multiple packs. The scaffolder handles composition — profiles from different packs don't conflict because they address different stakeholder groups.
Step 2 — Phase selection
Each pack ships a default phase preset, but you can override it. Five presets are available:
The presets define which lifecycle phases your project moves through and what gate criteria block each transition:
| Preset | Phases | Gate style |
|---|---|---|
grant | initiation → planning → execution → monitoring → closeout | Document-driven gates (MPA, ethics, IP) |
agile | discovery → development → release → maintenance | Sprint-aligned, lightweight gates |
waterfall | requirements → design → implementation → verification → deployment | Formal sign-off at each gate |
client-engagement | scoping → delivery → review → handoff | Client approval gates |
open-source | draft → alpha → beta → stable → maintenance | Community readiness checks |
For most teams starting fresh, agile is the right default. Grant-funded projects should use grant.
Step 3 — Project identity
The scaffolder asks for basic project information:
Project name: Acme Protein Extraction
One-liner: Pilot-scale protein extraction from canola meal
using enzymatic hydrolysis
Project kind: grant | internal | client | open_source
Start date: 2026-06-01
Lead contact: Jane Smith <jane@acme.com>
Organization: Acme BioTech Inc.
These values seed the manifest.yaml. Everything is editable later — the scaffolder just needs enough to generate a valid starting point.
Step 4 — Surfaces
Surfaces are the external systems where project-state can publish artifacts. The scaffolder presents each as a toggle:
Slack [off] Auto-post status updates to a channel
Gmail [off] Draft emails for review (never auto-sends)
Google Calendar [off] Propose meeting holds
Blog (scsiwyg) [on] Publish reports and updates
Project website [on] Live reference site on Vercel/Netlify
You can enable or disable any surface. Gmail is always draft-only — project-state will never send an email without human review. This is a design constraint, not a configuration option.
Step 5 — Review and confirm
The scaffolder shows a summary of all choices:
Pack: agile-default
Phase preset: agile
Current phase: 01-discovery
Project: Acme Protein Extraction
Kind: grant
Surfaces: blog, website
Lead: Jane Smith <jane@acme.com>
Confirm to proceed, or go back to change any step.
Step 6 — Build
The scaffolder creates the directory tree. Here's what it produces:
project-state/
├── manifest.yaml # Project identity, stakeholders, surfaces
├── reporting-matrix.yaml # What report, for whom, when, on which surface
├── state.json # Current phase, counters, harvest cursors
├── milestones/ # One YAML file per milestone
├── risks/ # One YAML file per risk
├── decisions/ # One YAML file per decision
├── changes/
│ ├── change-log/ # Non-material changes
│ └── change-orders/ # Material changes requiring approval
├── documents/
│ ├── inbox/ # Unclassified incoming documents
│ ├── references/ # Classified reference material
│ └── published/ # Published artifacts
├── logs/
│ └── activity.ndjson # Append-only activity log
├── packs/
│ └── agile-default/ # Loaded compliance pack
├── kanban/ # Local Next.js dashboard (port 3355)
└── website/ # Project website template (if enabled)
The manifest.yaml generated looks like this (from project-state's own substrate):
schema_version: 2
manifest_kind: project
project:
name: "project-state"
long_name: "The project-* skill suite — 28 skills + 7 compliance packs for project ops"
kind: "open_source"
start_date: "2026-04-24"
packs_loaded: ["agile-default"]
reporting_matrix_path: "reporting-matrix.yaml"
stakeholders:
- id: internal.team
organization: "Worksona"
role: "Project Team"
contacts:
lead: "David Olsson <david@atomic47.co>"
phases:
preset: "agile-default"
current_phase: "04-release"
surfaces:
slack:
enabled: false
gmail:
enabled: false
always_draft: true
blog:
enabled: true
site_slug: "project-state"
website:
enabled: true
framework: "nextjs"
hosting: "vercel"
The reporting-matrix.yaml gets seeded from the pack's defaults. It encodes "for each stakeholder group, what report at what cadence in what format on which surface, produced by which skill." The orchestrator reads this matrix on each invocation to decide what needs generating.
Coworker vs CLI
The scaffolder wizard is identical on both surfaces. The difference is presentation:
- Coworker renders each step as an HTML artifact with styled OptionCard, FormField, and ToggleCard components. You click to select.
- Claude Code renders the same steps as numbered lists, tables, and Mermaid code blocks. You type your choice.
The output is the same project-state/ directory either way.
Next step
The substrate exists but it's empty — no milestones, no risks, no context from your existing project documents. Onboarding shows how to turn documents into project context using the inbox-first approach.