# Manifest Schema

`.oagen-manifest.json` is a generated provenance artifact. It records what was generated, from which inputs, and when. It is machine-owned — humans should not edit it.

## Purpose

1. **Pruning** — On regeneration, oagen deletes files from the previous manifest that are no longer emitted, preventing stale-file accumulation
2. **Provenance** — Records the spec, emitter, and config used for each generation run
3. **Compat versioning** — Records the compat schema version for snapshot compatibility

## Schema (v2)

```json
{
  "version": 2,
  "language": "php",
  "sdkName": "acme-php",
  "generatedAt": "2026-04-18T22:02:14.077Z",
  "specSha": "sha256:abc123...",
  "specPath": "../openapi-spec/spec/open-api-spec.yaml",
  "emitterSha": "def456",
  "emitterVersion": "0.7.0",
  "configSha": "sha256:789abc...",
  "compatSchemaVersion": "1",
  "files": ["lib/Resource/CreateUser.php", "lib/Service/UserManagement.php"]
}
```

## Field Semantics

| Field                 | Type       | Required | Description                                                          |
| --------------------- | ---------- | -------- | -------------------------------------------------------------------- |
| `version`             | `number`   | yes      | Manifest schema version (currently `2`)                              |
| `language`            | `string`   | yes      | Emitter target language (e.g., `"php"`)                              |
| `sdkName`             | `string`   | no       | Human-readable SDK identity (e.g., `"acme-php"`)                     |
| `generatedAt`         | `string`   | yes      | ISO-8601 timestamp of the generation run                             |
| `specSha`             | `string`   | no       | SHA-256 hash of the source OpenAPI spec                              |
| `specPath`            | `string`   | no       | Path or reference to the source spec                                 |
| `emitterSha`          | `string`   | no       | Git SHA of the emitter code used                                     |
| `emitterVersion`      | `string`   | no       | Emitter version string                                               |
| `configSha`           | `string`   | no       | SHA-256 hash of the effective `oagen.config.ts`                      |
| `compatSchemaVersion` | `string`   | no       | Version of the compat snapshot schema                                |
| `files`               | `string[]` | yes      | Sorted list of generated file paths (relative to manifest directory) |

## Generated Ownership

The manifest is generated by `oagen generate` and written to the output directory. It should be committed to the SDK repository for pruning to work across regenerations.

**Never put human-authored content in the manifest.** Approvals, allowlists, and policy belong in `oagen.config.ts`. The manifest is regenerated on every run — any manual edits will be overwritten.

## Pruning Semantics

When `oagen generate` runs:

1. Read the existing `.oagen-manifest.json` (if present)
2. Compare the previous `files` list against the current emission set
3. Delete files that were previously generated but are no longer emitted
4. Only delete files whose contents start with the oagen generation header (when a header guard is available)
5. Write a new manifest with the current file list

On first adoption (no previous manifest), pruning is skipped.

## Backward Compatibility

The manifest reader accepts both v1 and v2 manifests. v1 manifests (which lack `sdkName`, `specSha`, etc.) are read successfully — the new fields are simply absent. A v1 manifest written by an older oagen version will work with the current pruning system.

If the manifest version is higher than supported, it is ignored with a warning.

## What Must Not Go in the Manifest

- Approvals or allowlists (human-authored → `oagen.config.ts`)
- Release thresholds (human-authored → `oagen.config.ts`)
- Manual exception records
- Policy overrides

The rule: **never make the generator rewrite a file that humans edit for policy.**
