# Codify Pipeline: Level A (Config-Only Edits)

Level A is the codify pipeline for changes that land in a single config file inside
`core/config/`. No new TypeScript files are created. The entire ceremony is: snapshot the target
file, propose the edit, write the edit, validate, and roll back on failure.

This pipeline is called by domain operations (identity, customers, offerings, roles, goals,
techStack, systems, actions, labels, and legacy feature compatibility) after the user has confirmed the proposed change. The caller provides
the specific field/block being changed, the proposed new value, and the target file.

---

## Pipeline

### Step 1: Snapshot

Before any write, read `TARGET_FILE` and keep the full file content in memory as the rollback
snapshot. Do not write any file during this step.

```
Read(TARGET_FILE)
-- store as ROLLBACK_SNAPSHOT
```

`TARGET_FILE` is the value the caller provides in the Caller Contract (see below). When the
project has not been split yet, callers pass the default
`core/config/organization-model.ts`.

### Step 2: Apply the edit

Use the Edit tool to apply the caller's proposed change to `TARGET_FILE`.

Rules for the edit:

- Edit only the specific field or block the caller specified. Do not reformat or restructure
  unrelated sections.
- For edits targeting `profile.ts`: preserve all other keys in `defineOrganizationModel({...})`
  exactly as they are.
- Maintain the existing code style (trailing commas, quote style, indentation) of the file.
- If the target field does not yet exist in the file, add it as a new property in the appropriate
  position (following the declared domain order in the schema).

### Step 3: TypeScript type-check

Run the type-check for the operations package:

```bash
pnpm -C operations check-types
```

Capture stdout and stderr. If the command exits non-zero, proceed to Step 5 (rollback).

### Step 4: Runtime schema validation

Confirm that the adapter's output passes `OrganizationModelSchema.parse()`. The adapter calls
`resolveOrganizationModel()` internally, which merges defaults with overrides and then parses the
result. A successful `check-types` pass is strong evidence that the schema is valid, but
cross-reference checks (segment ID refs in offerings, role reporting refs, period ordering in
goals) are runtime-only.

If the project exposes a validation script (e.g. `pnpm -C operations check`), run that too:

```bash
pnpm -C operations check
```

If either validation step fails, proceed to Step 5 (rollback).

### Step 5: Rollback (on failure only)

If Step 3 or Step 4 failed:

1. Write the ROLLBACK_SNAPSHOT content back to `TARGET_FILE` verbatim (use the Write tool with
   the exact snapshot content).
2. Confirm the file has been restored by checking that the content matches the snapshot.
3. Return the error message to the caller.

The caller is responsible for reporting the rollback to the user.

### Step 6: Success signal

If Steps 3 and 4 both passed, return a success signal to the caller with:

- The file edited (`TARGET_FILE`)
- The fields changed
- `Type-check: PASS`
- `Schema validation: PASS`

The caller formats and presents the final report.

---

## Caller Contract

Callers must provide before invoking this pipeline:

- **Target file:** the sub-file path to snapshot and edit. Default (unsplit projects):
  `core/config/organization-model.ts`. Split-project routing:
  - `core/config/organization-model/profile.ts` for identity, customers, offerings, roles, goals
    (and techStack/labels when those keys exist in `profile.ts`)
  - `core/config/organization-model/systems.ts` for systems, actions, resources
  - Callers use the default entry path when the domain does not yet have a dedicated sub-file
- **Target block:** the specific domain key or sub-key being changed (e.g. `identity`,
  `customers.segments`, `roles.roles`, `resources.hubspot`)
- **Proposed value:** the new TypeScript literal to write for that block
- **Confirmed:** the user has already said yes to the proposed change

This pipeline does not ask the user any questions. All confirmation happens in the domain
operation before this pipeline is invoked.
