---
name: ssp-ingest
description: Ingest documentation artifacts (policies, procedures, meeting transcripts, prior SSPs, ad-hoc notes) from the inputs/ folder and write them to the Halo SSP asset spine (Capability, Component, Control Implementation, Implemented Requirement, Implementation Statement, Set Parameter, system_information). Six-phase pipeline — classify → extract → reconcile → review (internal loop) → user-edit loop → compose→apply via the halo-action-pipeline — with CHANGE-PLAN diff-and-propose discipline, AFUUID idempotency, read-merge-write semantics, ODP values classified into first-class Set Parameter assets rather than IS prose, and a polished draft → user feedback → re-render flow until explicit approval. Per-phase doctrine + CHANGE-PLAN format spec live in reference-docs/ssp-ingest-phases.md. Load whenever the user runs /ssp-ingest, asks to "ingest SSP evidence", "update SSP assets from documents", or "load this transcript into Halo for the SSP."
---

# ssp-ingest — Documentation → Halo SSP Assets

## References

| Reference | Type | Location | When to Use |
|---|---|---|---|
| `ssp` | Skill | `plugins/grcitsm-analyst/skills/ssp/` | Write surfaces, canonical chain, routing |
| `halo-ssp-asset-model` | Skill | `plugins/grcitsm-analyst/skills/halo-ssp-asset-model/` | Field schema and relationships |
| `halo-ssp-asset-write-conventions` | Skill | `plugins/grcitsm-analyst/skills/halo-ssp-asset-write-conventions/` | The eight write rules including the framework-CF two-pass and write order |
| `ssp-capability-seed-list` | Skill | `plugins/grcitsm-analyst/skills/ssp-capability-seed-list/` | The 15 + starter Component mappings (and Proposed-New-Capability staging) |
| `ssp-review-standards` | Skill | `plugins/grcitsm-analyst/skills/ssp-review-standards/` | Phase 4 reviewer discipline applied to the CHANGE-PLAN |
| `grcitsm` | Skill | `plugins/grcitsm-analyst/skills/grcitsm/` | Broader Halo MCP catalog routing (asset-side workflow) |
| Ingest phase detail | Reference | `reference-docs/ssp-ingest-phases.md` | Full Phase 1/2/3/5/6 doctrine, the CHANGE-PLAN format spec, failure modes |
| `ssp-run-state.md` | File | `reference-docs/ssp-run-state.md` | State-file schema, atomic-write/resume discipline for every pipeline run |
| Write semantics | Reference | `reference-docs/halo-platform/write-semantics.md` | Null-handling (§2), lookup rules (§3), framework-CF ordering (§5), verify (§11) |

Pipeline workflow for turning any documentation input (policies, procedures, transcripts, prior SSPs, ad-hoc notes) into Halo SSP asset writes. Six phases, single command, in-chat approval gate, no Halo writes without explicit row-level approval.

This skill is the operational primer for the WRITE path. It composes [[ssp]] (write surfaces, canonical chain, routing), [[halo-ssp-asset-model]] (field schema and relationships), [[halo-ssp-asset-write-conventions]] (the eight write rules), [[ssp-capability-seed-list]], and [[grcitsm]] § Asset-side workflow. Read those first if you haven't. This page covers the pipeline shape and gates; per-phase mechanics and the CHANGE-PLAN format live in `reference-docs/ssp-ingest-phases.md`.

## When to load this skill

- User types `/ssp-ingest` (with or without flags).
- User asks to "ingest SSP evidence from these documents", "load this transcript into the SSP", "update SSP assets from the uploaded policy", or similar phrasing.
- User has dropped files into `inputs/` and wants them turned into Halo SSP writes.

## Site targeting

`/ssp-ingest` requires a Site. Resolution order:

1. **`--site-id <N>`** — direct numeric Site ID. Most explicit; agent uses it as-is.
2. **`--client-name "<X>"`** — resolve via `system_information` lookup. If exactly one match, use it. If multiple, prompt the user to disambiguate by Site ID.
3. **Neither flag provided** — list available Sites from `system_information` and prompt the user to pick. Do not infer from input file content.

Once resolved, capture `client_id` and `site_id` (often the same as system_id) into the run state and pass to every subsequent `create_asset` call.

## Pipeline orchestration

The spine has six asset types — Capability, Component, Control Implementation, Implemented Requirement, Implementation Statement, and Set Parameter (dtype 193, the OSCAL `set-parameter` leaf for ODP values) — plus the Site-level `system_information` surface. ODP values are first-class SP assets, NOT prose folded into Implementation Statements.

```
Phase 1 — Classify       \
Phase 2 — Extract         > ssp-curator agent
Phase 3 — Reconcile      /

Phase 4 — Review            ssp-reviewer agent
                            (internal loop until clean OR halt on BLOCKER)

Phase 5 — User-edit loop    main agent coordinates
                            (render polished draft → user response → if edits:
                             mutate + re-invoke ssp-reviewer for Phase 4 + re-render
                             until user approves)

Phase 6 — Compose → Apply   main agent orchestrates
                            (only after explicit user approval:
                             reconcile_ssp_assets → ssp_compile.py over the
                             Phase-3 manifests → ssp-writer composes residual
                             actions → /grcitsm-analyst:halo-apply → relationship
                             reconcilers → verify pass)
```

The main agent (you) is the orchestrator. Per phase, load the phase's doctrine from `reference-docs/ssp-ingest-phases.md` and either delegate to a subagent via the Agent tool OR carry out the phase inline.

## The 6 phases — map and gates

Full mechanics for each phase: `reference-docs/ssp-ingest-phases.md`. The map, outputs, and the rules that gate each transition:

### Phase 1 — Classify

Read every file under `inputs/`; tag each with kind, scope (`system_information` / Capability / Component / IR / IS / SP / multi), candidate capabilities, components, and controls. A statement naming a concrete value for a control's `[Assignment: organization-defined ...]` slot is `SP` scope, not `IS`. Output: `classification.jsonl` (one row per input file).

### Phase 2 — Extract

Pull structured evidence statements per file: text (≤ ~400 chars, verbatim or near-verbatim), citation (file:line for documents; speaker@timestamp+filename for transcripts), claim_type (identity / implementation / attribution / odp_value / narrative), target_scope, target_identifier, controls. ODP values are tagged `odp_value` and never buried in IS-bound implementation statements. Output: `evidence.jsonl`. Transcript / document / prior-SSP extraction specifics: `reference-docs/ssp-ingest-phases.md`.

### Phase 3 — Reconcile

Diff every statement against live Halo state (AFUUID match first, then canonical identity per type) and decide `CREATE` / `UPDATE` / `NO-OP` / `MERGE-CANDIDATE`; unmapped Components stage as `PROPOSED-NEW`. Two structural rules gate this phase:

- **The framework-spine shell is reconciler-owned, not document-driven.** Capabilities, Control Implementations, and Implemented Requirements are catalog-derived and materialized by `reconcile_ssp_assets` in Phase 6 — never emit bare shell CREATE rows from documents; documents drive narrative and chosen values only.
- **Never invent an ODP value.** An ODP slot with no value in the inputs surfaces as an UNFILLED-ODP gap row.

Output: `change-plan.md` + `change-plan.jsonl` (primary handoff to Phase 4), plus a projection of the reconciled structure into the four flat CSV manifests (`manifests/components.csv`, `cap-component-rel6.csv`, `odp-parameters.csv`, `is-manifest.csv`) + AFUUID-keyed `companions/IS-*.md` narrative files, consumable by `/grcitsm-analyst:ssp-compile` (column contracts: [[ssp-manifest-schemas]]; compile discipline: [[ssp-csv-compile]]). The manifests are a projection only — the CHANGE-PLAN stays the primary Phase-4 handoff, and the manifests carry no reconciler-owned rows (Capabilities/CIs/IRs, CI→IR/IR→IS/IR→SP/CI→SP). Identity-matching keys, library bindings, and SP reconciliation detail: `reference-docs/ssp-ingest-phases.md`.

### Phase 4 — Review (internal loop)

Hand off the reconciled CHANGE-PLAN to the `ssp-reviewer` agent. See [[ssp-review-standards]] for full discipline. Short version:

- **Two-tier model:** BLOCKER (halts the run) and AUTO-FIX (silently applied during the loop). No SUGGESTION tier.
- **Internal loop:** review → auto-fix → re-review until zero BLOCKERs + zero new AUTO-FIX, max 5 passes.
- **Halt-on-BLOCKER:** any unresolved BLOCKER halts the entire run (no writes); user resolves and re-runs.
- **Output of this phase:** a polished CHANGE-PLAN ready for the user. Full audit in `outputs/ssp-ingest-{date}-{run-id}/review-log.md`.

### Phase 5 — User-edit loop (outer)

Render the polished CHANGE-PLAN inline in chat (with Reviewer Notes summary) and pause for approve / cancel / edit feedback. On edits: mutate the plan rows, **re-run Phase 4 against the modified plan**, re-render, log the iteration in `user-iterations.md`, and pause again — loop until explicit approve or cancel. **No write tool fires until the user has explicitly approved the current iteration's draft.** Response shapes and mutation procedure: `reference-docs/ssp-ingest-phases.md`.

### Phase 6 — Compose → Apply

Fires only after explicit user approval; no compose happens before it. The approved plan rides the [[halo-action-pipeline]] — nothing in this phase hand-applies via direct MCP write calls. Sequence (main agent orchestrates): `reconcile_ssp_assets` (direct MCP — scaffolds Capabilities / CIs / IRs first) → snapshot + library CSVs (read-only) → `ssp_compile.py` compiles the Phase-3 manifests + companions into `state/actions-01.jsonl` (all structure, library-first, three-phase CFs — [[ssp-csv-compile]]) → the `ssp-writer` agent composes the residual rows the manifests can't carry (system_information merge, non-manifest UPDATEs, merge resolutions, IR Description rollups) into `state/actions-02.jsonl`, never calling a write tool → `/grcitsm-analyst:halo-apply` applies both step files (executor fleet, `state/progress.jsonl` ledger) → the four `reconcile_ssp_relationships_*` sweeps run direct at their spine positions → verify pass (sampled `get_asset` per Rule 7; project `uuid-map.jsonl` from the ledger). Resume = re-run halo-apply against the same run folder, `doneIds` from the ledger. Full orchestration + row-class routing: `reference-docs/ssp-ingest-phases.md` § Phase 6.

## CHANGE-PLAN format

The full format spec (section-by-section structure, row numbering, PROPOSED-NEW / UNFILLED-ODP / MERGE-CANDIDATE sections, the approval prompt): `reference-docs/ssp-ingest-phases.md` § CHANGE-PLAN format. Partial approval is supported: approving "rows 1-7, 30, 50-51" applies just those rows; everything else is skipped.

## Output folder layout

```
outputs/ssp-ingest-2026-05-25-r42/
  classification.jsonl       # Phase 1 — one row per input file
  evidence.jsonl             # Phase 2 — one row per extracted statement
  change-plan.md             # Phase 3 — the human-readable plan (also rendered inline in chat)
  change-plan.jsonl          # Phase 3 — machine-readable form Phase 5 consumes
  manifests/*.csv            # Phase 3 — structural CSV manifests (compiled in Phase 6)
  companions/IS-*.md         # Phase 3 — AFUUID-keyed narrative files for off-library IS rows
  state/actions-01.jsonl     # Phase 6 — compiled structural actions (ssp_compile.py)
  state/actions-02.jsonl     # Phase 6 — residual actions composed by ssp-writer
  state/progress.jsonl       # Phase 6 — append-only apply ledger (halo-action-pipeline; the resume surface)
  uuid-map.jsonl             # Phase 6 — AFUUID → asset_id, projected from the ledger (read by future runs)
```

The folder name encodes the run ID (`r42` = 42nd ingest run on this date). Increment on each run.

## What this skill does NOT do

- **Does not write to Halo without explicit approval** — Phase 5 is gated on Phase 4 response.
- **Does not infer the Site** — `--site-id` or `--client-name` resolution is mandatory.
- **Does not auto-create Capabilities/Components from unmapped evidence** — those stage as PROPOSED-NEW rows for approval.
- **Does not retitle / reparent / delete existing IR or IS rows silently** — those refactor moves are explicit UPDATE / LINK rows in the CHANGE-PLAN. See [[halo-ssp-asset-write-conventions]] § Rule 4.
- **Does not fold ODP values into IS narrative, and does not fabricate them** — organization-defined parameter values are modeled as first-class Set Parameter assets (dtype 193) carrying the value in field 236, parented to the IR (rel 12) or CI (rel 11). An ODP slot with no value in the input artifacts is surfaced as an UNFILLED-ODP gap row, never invented.
- **Does not write to Halo tickets** — `agent_note` and ticket-side tools are out of scope for SSP ingest. The cross-reference between the change-plan and Halo's native change history is sufficient — Halo's asset UI already records every field-level write with timestamp.
- **Does not process diagrams** — image files in `inputs/` are logged and skipped. Diagram support is a later milestone.
- **Does not handle inventory items beyond Cloud Asset → Component links** — Inventory expansion is a separate concern.

## Failure modes

Symptom → cause → response table (Site targeting, empty plans, cleared-field verifies, framework-CF ordering, spine-order violations, multi-baseline sites, dropped lookup values): `reference-docs/ssp-ingest-phases.md` § Failure modes.

## Run state files

Every run produces a `state.json` pointer file plus the slice files listed above. The state-file convention — schema, update cadence, atomic writes, resume discipline — is defined in `reference-docs/ssp-run-state.md`. Every agent in the pipeline reads `state.json` at start and updates it (atomically) at every transition. The user can interrupt any run, return later, and resume from `next_action`.

## Cross-references

- [[ssp]] — write surfaces, canonical chain, routing.
- [[halo-ssp-asset-model]] — field schema.
- [[halo-ssp-asset-write-conventions]] — the eight write rules.
- [[ssp-capability-seed-list]] — the 15.
- [[grcitsm]] — broader Halo MCP workflow.
- `reference-docs/ssp-ingest-phases.md` — per-phase mechanics + CHANGE-PLAN format spec.
