# Scaffold: New OM Entries via `om:scaffold:*` CLI

`om:scaffold:*` is the guided-creation surface for adding new entries to the tenant Organization Model. Each command prompts for missing fields, prints the proposed TypeScript / MDX block under `--dry-run`, and (when run without `--dry-run`) writes into the canonical authoring file under `core/config/organization-model/**` or `core/config/knowledge/nodes/`.

This operation is invoked by `/om` when intent classifies as **Codify-new-entry** (a net-new System, Resource, Role, Knowledge node, or a fill-pass against a conformance-gap JSON) rather than a Level-A field edit. For existing-field edits, dispatch to `codify-level-a.md` instead.

---

## When to Use

| Intent signal                                   | Dispatch                         |
| ----------------------------------------------- | -------------------------------- |
| "Add a new system for …", "we have an X system" | `om:scaffold:system`             |
| "Add a workflow / resource called …"            | `om:scaffold:resource`           |
| "Add a role …", "we need a … role"              | `om:scaffold:role`               |
| "Add a knowledge node / playbook / strategy …"  | `om:scaffold:knowledge`          |
| Conformance gate produced a gap JSON to apply   | `om:scaffold:fill --gaps <path>` |

For existing-field edits (changing a description, toggling a system, renaming a label), use the Codify Level-A ceremony — do not scaffold.

---

## CLI Surface

All commands run from inside `external/<project>/` (or any descendant — `elevasis-sdk` walks up to the `.elevasis` marker). Add `--dry-run` to any command to preview the generated TypeScript / MDX without writing.

| Command                 | Purpose                                                                                              | Writes to                                   |
| ----------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `om:scaffold:system`    | Guide creation of a new System entry. Optional `--api-backed` emits an `apiInterface` block.         | `core/config/organization-model/systems.ts` |
| `om:scaffold:resource`  | Add a new workflow Resource descriptor with `systemPath` attachment and an ontology `primaryAction`. | `core/config/organization-model/systems.ts` |
| `om:scaffold:role`      | Add a new Role to the profile domain.                                                                | `core/config/organization-model/profile.ts` |
| `om:scaffold:knowledge` | Create a new MDX knowledge node file under the requested kind / system mount.                        | `core/config/knowledge/nodes/`              |
| `om:scaffold:fill`      | Non-interactive apply of a conformance-gap JSON produced by the conformance gate (Agent 2a).         | Per-file as recorded in the JSON.           |

---

## Common Options

| Flag                        | Behavior                                                                             |
| --------------------------- | ------------------------------------------------------------------------------------ | -------- | --------- | -------- |
| `--dry-run`                 | Print proposed block; write nothing. Always run this first when in doubt.            |
| `-h`, `--help`              | Print command-specific help.                                                         |
| `--id <id>`                 | Pre-fill the canonical id (prompted if absent).                                      |
| `--title <title>`           | Pre-fill display title (prompted if absent — `system`, `resource`, `role`).          |
| `--system-path <path>`      | Attach Resource or Knowledge to an existing System (prompted if absent).             |
| `--api-backed`              | (`system` only) Emit an `apiInterface` block; reminds you to populate `resourceIds`. |
| `--primary-action <action>` | (`resource` only) Pre-fill ontology primary action id.                               |
| `--kind <kind>`             | (`knowledge` only) `playbook                                                         | strategy | reference | policy`. |
| `--gaps <path>`             | (`fill` only) Required path to the conformance-gap JSON.                             |
| `--skipped <path>`          | (`fill` only) Output path for gaps that still need manual input.                     |

---

## Step-by-Step

### Step 1: Pre-flight read

Before scaffolding, run a single `om:describe` against the parent System (for Resource / Knowledge scaffolds) or the profile domain (for Role scaffolds). This grounds the proposed id, system path, and ontology references in current model state. Skipping this step routinely produces ids that collide with existing entries.

```bash
pnpm exec elevasis-sdk om:describe sales.crm
```

### Resource placement decision

For `om:scaffold:resource`, never choose `systemPath` because the new Resource is a workflow,
agent, script, or trigger. Those are Resource kinds, not Systems. Pick the existing System that
owns the business or platform capability the Resource operates.

If no existing System owns that capability, first propose a real capability System. Do not create
`automation`, `workflows`, `operations`, `monitoring`, `settings`, or similarly broad bucket
Systems to make the Resource fit.

### Step 2: Dry-run

Always preview first. Each command prints the exact TypeScript / MDX block it would write.

```bash
pnpm exec elevasis-sdk om:scaffold:system --dry-run
pnpm exec elevasis-sdk om:scaffold:resource --dry-run
pnpm exec elevasis-sdk om:scaffold:role --dry-run
pnpm exec elevasis-sdk om:scaffold:knowledge --dry-run
```

The dry-run output is the diff you would present to the user during a Codify proposal. Show it verbatim before asking for confirmation.

### Step 3: Confirm

Pause for explicit user confirmation, exactly like Codify Level-A Step 3. Permission prompts also gate the underlying write.

### Step 4: Write

Re-run the command without `--dry-run`. The CLI:

1. Asserts the project is in split layout (`core/config/organization-model/{profile,systems,navigation}.ts`); on monolithic projects it errors with a guidance message rather than guessing where to write.
2. Inserts the new block alongside existing entries of the same kind.
3. Reports the touched file path.

### Step 5: Validate

Always run both gates after a scaffold write:

```bash
pnpm -C operations check-types   # type-check only, no emit
pnpm -C operations check         # elevasis-sdk resource validator (incl. conformance gate)
```

The new conformance gate (shipped in `@elevasis/sdk@1.30+`) will catch a System that declares API-backed Resources but no `apiInterface`. If it fires after a `system` scaffold, either:

- Re-run `om:scaffold:system --api-backed` to add the `apiInterface` block, or
- Run `om:scaffold:fill --gaps <gaps.json>` against the gate's emitted gaps file.

### Step 6: Rollback on failure

If either validation gate fails, restore the touched file from the snapshot captured in Step 1 of the parent `/om` Codify ceremony. The scaffold CLI does not perform its own rollback — the ceremony around it does.

---

## `om:scaffold:fill` — Conformance Gap Pass

`om:scaffold:fill` is the non-interactive counterpart to the four guided scaffolders. It consumes a JSON file shaped like the output of the conformance gate (the new deploy preflight introduced alongside `@elevasis/core@0.38` + `@elevasis/sdk@1.30`) and writes the missing fields it can derive without user input. Gaps that require a choice (e.g. picking a `readinessProfile`) land in the `--skipped` output for manual review.

```bash
# After the conformance gate prints a gaps file:
pnpm exec elevasis-sdk om:scaffold:fill --gaps .elevasis/conformance-gaps.json --dry-run
pnpm exec elevasis-sdk om:scaffold:fill --gaps .elevasis/conformance-gaps.json --skipped .elevasis/conformance-skipped.json
```

`fill` is idempotent for already-applied gaps; it skips entries that no longer match the live model.

---

## Layout Guard

Every `om:scaffold:*` command requires the split layout under `core/config/organization-model/`:

- `profile.ts` — identity, customers, offerings, roles, goals, techStack, labels
- `systems.ts` — systems + system-attached resources
- `navigation.ts` — navigation surfaces and sidebar wiring

On a monolithic `core/config/organization-model.ts`, the command errors with a one-line instruction to split first. The split step is owned by an upstream `/om` workflow — do not hand-split during a scaffold.

---

## Related Operations

- `codify-level-a.md` — existing-field edits (the default Codify pipeline)
- `codify-level-b.md` — net-new Zod extension files under `core/config/extensions/`
- `verify.md` — model-coherence checks (the in-memory doctor)

---

## Caller Contract (when dispatched from `/om`)

When `/om` classifies a Codify-new-entry intent, it should:

1. Pick the correct sub-command from the table above.
2. Pre-fill any options it can confidently extract from the conversation (`--id`, `--title`, `--system-path`, `--api-backed`, etc.) so the CLI does not re-prompt for them.
3. Always pass `--dry-run` on the first invocation and show the output to the user.
4. On user confirmation, re-invoke without `--dry-run`.
5. Run the Step 5 validators and report the result. Roll back if either fails.

Do not skip the dry-run round-trip. The scaffolders write into the authoring source of truth — silent writes erode the trust the `/om` ceremony exists to protect.
