Skip to content
scsiwygest. ‘26
Sign in
get startedmcpcommunityapiplaygroundswaggersign insign up
project-state·Customization — packs, matrix, and custom phases28 May 2026David Olsson
project-state

Customization — packs, matrix, and custom phases

What you need: A working project-state/ substrate. Familiarity with phase gates helps.


project-state's behavior comes from configuration, not code. Six skills are profile-driven — their behavior changes based on which YAML profiles are loaded. Profiles are shipped by compliance packs. The reporting matrix determines what gets generated and when. Phase presets define the lifecycle. All of it is editable YAML.

What a pack contains

A pack is a directory under packs/ with a fixed structure:

packs/agile-default/
├── manifest.yaml                    # Pack identity and version
├── README.md                        # What this pack does
├── profiles/
│   └── review-meeting.yaml          # Profile for project-review-meeting
└── reporting-matrix-defaults.yaml   # Entries to seed into the matrix

Here's the agile-default pack's manifest:

pack:
  id: "agile-default"
  name: "Agile Engineering Defaults"
  version: "0.1.0-starter"
  compatible_core: ">=2.0,<3.0"
  description: |
    Pack for engineering teams running Scrum/Kanban with release trains.
    Configures sprint cadence, retro templates, release-phase model.
    Does not assume a funder or customer; pair with another pack for those.
  maturity: "starter"

provides:
  profiles:
    - review-meeting
    - phase-gate
  reporting_matrix_defaults: true

The provides.profiles array lists which skill profiles this pack ships. The reporting_matrix_defaults: true flag means the scaffolder will merge this pack's default matrix entries into the project's reporting matrix during setup.

Pack composition

Packs compose. Load agile-default for sprint ceremonies and sred-canada for SR&ED tracking on the same project:

yaml
# manifest.yaml
project:
  packs_loaded: ["agile-default", "sred-canada"]

Each pack provides profiles for different skills. agile-default provides review-meeting (sprint retrospective format). sred-canada provides sred-tracker and sred-reviewer (SR&ED work capture and claim review). They don't conflict because they address different skills and different stakeholder groups.

When two packs provide profiles for the same skill (e.g., both ship a phase-gate.yaml), the profiles merge: criteria from both packs apply. If there's a direct conflict (same criterion ID, different check), the pack loaded later wins.

Editing the reporting matrix

The reporting matrix is a YAML file you edit directly. Here's a before-and-after example — adding a monthly technical brief:

Before:

yaml
entries:
  - id: monday-tracker-email
    stakeholder_group: internal.team
    report: "Monday tracker email"
    cadence: { kind: weekly, day: monday, lead_time_hours: 8 }
    format: md
    surface: blog
    generator: project-status-reporter

After:

entries:
  - id: monday-tracker-email
    stakeholder_group: internal.team
    report: "Monday tracker email"
    cadence: { kind: weekly, day: monday, lead_time_hours: 8 }
    format: md
    surface: blog
    generator: project-status-reporter

  - id: monthly-technical-brief
    stakeholder_group: internal.team
    report: "Monthly technical brief"
    cadence: { kind: monthly, day_of_month: 1, lead_time_hours: 24 }
    format: md
    surface: gmail
    generator: project-status-reporter
    description: |
      Monthly summary of technical progress, architecture decisions,
      and upcoming technical milestones. Sent as Gmail draft to team lead.

The orchestrator picks up the new entry on its next invocation. No restart, no config reload — it reads the file every time.

Each entry needs five fields: stakeholder_group (who), report (what), cadence (when), surface (where), generator (which skill). The format and description fields are optional but useful for clarity.

Writing a custom phase preset

Phase presets are YAML files in templates/phase-presets/. To create a custom lifecycle:

# templates/phase-presets/research-to-production.yaml
id: research-to-production
name: "Research to Production Pipeline"
phases:
  - id: "01-research"
    name: "Research"
    gate_in: []
    gate_out:
      - id: lit_review
        label: "Literature review published"
        check: "documents/published/lit-review-*.md exists"
      - id: hypothesis_defined
        label: "Research hypothesis documented"
        check: "decisions/*-hypothesis.yaml exists"

  - id: "02-prototype"
    name: "Prototype"
    gate_in:
      - id: research_done
        label: "Research phase completed"
    gate_out:
      - id: prototype_validated
        label: "Prototype validated against acceptance criteria"
      - id: stakeholder_demo
        label: "Stakeholder demo completed"

  - id: "03-scale"
    name: "Scale"
    gate_in:
      - id: prototype_accepted
        label: "Prototype accepted by stakeholders"
    gate_out:
      - id: performance_targets
        label: "Performance targets met at scale"

  - id: "04-production"
    name: "Production"
    gate_in:
      - id: scale_validated
        label: "Scale validation complete"
    gate_out: []

Reference it in your manifest:

yaml
phases:
  preset: "research-to-production"
  current_phase: "01-research"

The phase-gate skill reads your custom preset and enforces its gates. No code changes needed.

Authoring a new pack

A new pack follows the same directory structure. The full authoring guide is in docs/PACK-AUTHORING.md. The essential steps:

  1. Create packs/<your-pack-id>/manifest.yaml with pack identity
  2. Add profile YAMLs under profiles/ for each skill you want to configure
  3. Add reporting-matrix-defaults.yaml with matrix entries for your stakeholder groups
  4. Set maturity: "starter" until the pack has been used on a real project

The six profile-driven skills that packs can configure:

SkillProfile controls
project-review-meetingMeeting format, agenda template, cadence
project-funder-reportingReport structure, required sections, submission format
project-external-commsReview pipeline, approval chain, audience tiers
project-ip-trackerDisclosure format, recipient, filing workflow
project-phase-gateGate criteria additions/overrides per phase
project-archiveCloseout checklist, retention policy, handoff artifacts

Each skill looks for its profile at packs/<pack-id>/profiles/<skill-name>.yaml. If the profile exists, the skill loads it. If not, the skill uses its built-in defaults.

The design system as extension point

The interactive scaffolding design system (ProgressBar, OptionCard, FormField, ToggleCard, NavRow) is documented as a fifth extension point. Custom skills that present wizard-like flows can reuse the same components for visual consistency across both Coworker and Claude Code surfaces. The component specifications are in the scaffolder's SKILL.md.

Next step

The substrate is configured, the packs are loaded, the matrix is tuned. But where does the information that feeds all of this come from in the first place? Harvesting intelligence shows how project-state pulls signals from Slack, Gmail, Google Docs, and scsiwyg into the inbox for triage and classification.