# Source Registry Admin Dry-Run Command Parser V01

Issue: [#333](https://github.com/pinklon/ai-capability-discipline/issues/333)

Date: 2026-06-27

Repository: `pinklon/ai-capability-discipline`

Baseline commit: `512fcba07ce21a10342bb4d776860ec0509372dd`

Status: dry-run parser and validation slice only. This ticket adds a dry-run parser only. This ticket does not implement live Source Registry Admin commands, does not mutate source registries, does not mutate Preview or Production source sets, does not enable sources, does not disable sources, does not retire sources, does not promote sources, does not use Cloudflare CLI or API, does not call external URLs, does not change provider or model configuration, does not change runtime retrieval behavior, does not change package authority, does not start Production apply, does not start OKF implementation, does not start Google SDLC implementation, does not start multi-agent orchestration implementation, does not create Source Registry Admin live implementation child issues, does not create extraction-profile implementation tickets, does not close #271, does not reopen #269, does not close #269, and does not apply `codex-automerge`.

## Purpose

Add the first repo-local dry-run Source Registry Admin command parser.

The parser accepts structured command requests, validates command shape, validates source-record inputs through the existing schema/lifecycle foundation, applies lifecycle and environment precondition checks for a bounded deep-validation subset, refuses unsafe requests, and emits receipt-preview output for future mutating commands.

The parser is intentionally dry-run only. It produces deterministic JSON evidence and performs no source registry, source-set, runtime, provider, Cloudflare, or package-authority mutation.

## Relationship To Source Registry Admin Product Requirements

#325 / PR #326 defines Source Registry Admin product requirements.

The product requirements define Source Registry Admin as the governed source lifecycle administration capability for enrichment lanes. This dry-run parser uses those requirements to preserve the lifecycle, approval, citation, receipt, environment, and authority-lane boundaries before live command implementation exists.

This ticket does not create live administrative authority.

## Relationship To Command Contract

#329 / PR #330 defines Source Registry Admin command contract v01.

The dry-run parser recognizes every command named by the command contract. It implements command recognition for the full contract and deep validation for the bounded subset selected for this slice.

This ticket does not replace the command contract. It makes the contract testable through repo-local fixtures and deterministic dry-run output.

## Relationship To Schema/Lifecycle Validation

#331 / PR #332 defines Source Registry Admin schema and lifecycle validation.

The dry-run parser reuses `validation/fixtures/source_registry_admin/source_record_schema_v01.json` and the validator logic from `validation/scripts/check_source_registry_admin_schema_lifecycle.py`.

The parser validates source-record inputs through the existing `source_record_schema_v01` guardrails and validates lifecycle transition context through the existing lifecycle transition checks. It does not duplicate schema ownership.

## Non-Goals

This dry-run parser slice does not:

- implement live Source Registry Admin commands
- mutate source registries
- mutate Preview or Production source sets
- enable, disable, retire, or promote any source
- use Cloudflare CLI or API
- call external URLs
- change provider or model configuration
- change runtime retrieval behavior
- change package authority
- start Production apply
- start OKF implementation
- start Google SDLC implementation
- start multi-agent orchestration implementation
- create Source Registry Admin live implementation child issues
- create extraction-profile implementation tickets
- close #271
- reopen #269
- close #269
- approve arbitrary web search
- approve user-provided URL retrieval outside governed `add_source`
- approve browser-side source fetch
- approve deletion semantics that erase audit history
- apply `codex-automerge`

## Dry-Run Parser Behavior

The parser is `scripts/source_registry_admin_dry_run.py`.

It accepts:

- `--input`, a JSON file containing one command request, a list of command requests, or an object with a `cases` list
- `--command`, an optional command-name override for a single input object
- `--case-id`, an optional fixture case selector

The parser returns JSON. A successful request exits with code `0`. A refused request exits with code `1`. Multi-case input exits with code `1` if any case is refused.

The parser never writes source registry files, never writes Preview or Production source-set files, never calls Cloudflare, never calls external URLs, and never changes runtime behavior.

## Supported Command Coverage

Commands recognized:

- `add_source`
- `approve_source`
- `register_source`
- `validate_source`
- `enable_preview`
- `disable_preview`
- `mark_production_eligible`
- `promote_to_production`
- `disable_production`
- `emergency_disable`
- `rollback_registry`
- `retire_source`
- `list_sources`
- `list_active_sources`
- `show_source_detail`
- `generate_receipt`
- `run_source_smoke`

Commands deeply validated in this slice:

- `add_source`
- `validate_source`
- `enable_preview`
- `promote_to_production`
- `emergency_disable`
- `retire_source`

Deferred command validation:

- `approve_source`
- `register_source`
- `disable_preview`
- `mark_production_eligible`
- `disable_production`
- `rollback_registry`
- `list_sources`
- `list_active_sources`
- `show_source_detail`
- `generate_receipt`
- `run_source_smoke`

Deferred command validation is candidate next work only. No tickets are created by this slice.

## Input Model

Each command request may include:

- `command`
- `source_id`
- `source_record`
- `source_records`
- `lifecycle_transition`
- `environment_eligibility`
- `validation_status`
- `receipt_refs`
- `last_known_good_registry_ref`
- `disable_reason`
- `retirement_reason`
- `audit_history_preserved`
- refusal probes such as `search_mode`, `retrieval_request_mode`, `fetch_surface`, `audit_disposition`, and live mutation request flags

When `source_record` or `source_records` are provided, the parser validates them against the existing source-record schema and guardrails.

## Output Model

Successful dry-run validation includes:

- `dry_run: true`
- `command`
- `status`
- `source_id` when applicable
- `current_lifecycle_state` when applicable
- `proposed_lifecycle_state` when applicable
- `current_active_environments` when applicable
- `proposed_active_environments` when applicable
- `validation_checks`
- `refusal_checks`
- `receipt_preview`
- `mutations_performed: false`
- `boundary_confirmations`

Refused dry-run validation includes:

- `dry_run: true`
- `command`
- `status: refused`
- `reason`
- `failed_checks`
- `mutations_performed: false`
- `boundary_confirmations`

## Refusal Behavior

The parser refuses invalid command shape, invalid source-record inputs, invalid lifecycle preconditions, invalid environment preconditions, invalid authority-lane requests, unsafe retrieval behavior, audit-history deletion semantics, and requests for live mutation outside dry-run mode.

Refusal coverage includes:

- unknown command
- missing command
- missing source ID
- duplicate source ID in command input sets where applicable
- wildcard origin
- broad path prefix
- package-authority promotion
- active source without approval
- Production enablement without Production eligibility
- Production enablement without validation
- retired source reactivation
- source deletion that erases audit history
- arbitrary web search
- user-provided URL retrieval outside governed `add_source`
- browser-side source fetch
- command that would require live mutation outside dry-run mode

## Receipt-Preview Behavior

Successful dry-run output includes `receipt_preview`.

The receipt preview records:

- schema `source_registry_admin_dry_run_receipt_preview_v01`
- command name
- source ID when applicable
- previous lifecycle state when applicable
- proposed lifecycle state when applicable
- previous active environments when applicable
- proposed active environments when applicable
- whether a receipt would be required before future live mutation
- `mutations_performed: false`
- boundary confirmations

The receipt preview is evidence, not execution.

## Fixture Strategy

Fixtures live under `validation/fixtures/source_registry_admin/`:

- `dry_run_commands_valid_v01.json` covers valid dry-run parsing, all command recognition, and deep validation for the selected subset.
- `dry_run_commands_invalid_v01.json` covers refusal behavior and expected failure reasons.

The dry-run parser also reads existing schema/lifecycle fixtures:

- `source_record_schema_v01.json`
- `source_lifecycle_transitions_v01.json`
- `source_records_valid_v01.json`
- `source_records_invalid_v01.json`

## Validation Coverage

The focused validator is `validation/scripts/check_source_registry_admin_dry_run_command_parser.py`.

It checks:

- dry-run script exists
- documentation artifact exists
- valid dry-run command fixtures pass
- invalid dry-run command fixtures fail for expected reasons
- dry-run outputs include `dry_run: true`
- dry-run outputs include `mutations_performed: false`
- receipt-preview output exists
- unknown commands are refused
- live mutation is refused or impossible
- all command names from the command contract are recognized
- deep validation subset is documented
- boundary strings are present
- relationship to #325 / PR #326 product requirements is present
- relationship to #329 / PR #330 command contract is present
- relationship to #331 / PR #332 schema/lifecycle validation is present
- no source registry mutation is performed

The validator is wired into `validation/scripts/run_all.py`.

## Boundary Confirmations

- #325 / PR #326 defines Source Registry Admin product requirements.
- #329 / PR #330 defines Source Registry Admin command contract v01.
- #331 / PR #332 defines Source Registry Admin schema and lifecycle validation.
- This ticket adds a dry-run parser only.
- This ticket does not implement live Source Registry Admin commands.
- This ticket does not mutate source registries.
- This ticket does not mutate Preview or Production source sets.
- This ticket does not start #271.
- #271 remains the extraction-profile lane.
- #271 remains open.
- #269 remains closed.
- #269 was not reopened.
- #269 was not closed by this ticket.
- No Source Registry Admin live implementation child issues were created.
- No extraction-profile implementation tickets were created.
- No source registries were mutated.
- No source sets were mutated.
- No source was enabled, disabled, retired, or promoted.
- No Cloudflare CLI or API was used.
- No external URLs were called.
- No provider or model configuration was changed.
- No runtime retrieval behavior was changed.
- No package authority was changed.
- No Production apply was started.
- No OKF implementation was started.
- No Google SDLC implementation was started.
- No multi-agent orchestration implementation was started.
- `codex-automerge` was not applied.

## Post-Closeout Next Action

Explicit owner decision point:

After this dry-run parser slice is merged and locally closed out, choose whether to add dry-run source admin receipt schema enforcement or continue extraction-profile work for the next source.

Do not start either path by assumption.
