Add semantic configuration profile comparison
This commit is contained in:
26
docs/cli.md
26
docs/cli.md
@@ -20,7 +20,7 @@ Top-level commands:
|
||||
- `publish <session_id>`: force-run publish.
|
||||
- `clean <session_id>` or `clean --all`: remove local work/spool state.
|
||||
- `session <subcommand>`: session helper commands.
|
||||
- `config <subcommand>`: validate or display resolved pipeline configuration.
|
||||
- `config <subcommand>`: validate, display, source-trace, or compare resolved pipeline configuration.
|
||||
|
||||
Session subcommands:
|
||||
|
||||
@@ -78,12 +78,13 @@ Commands with additional positionals keep their command-specific order:
|
||||
|
||||
## Command Reference
|
||||
|
||||
### `config validate`, `config show`, and `config sources`
|
||||
### `config validate`, `config show`, `config sources`, and `config diff`
|
||||
|
||||
```bash
|
||||
narratio config validate [--config <pipeline.yml>] [--campaign <id> | --campaign-file <campaign.yml>] [--profile <name>]
|
||||
narratio config show [--config <pipeline.yml>] [--campaign <id> | --campaign-file <campaign.yml>] [--profile <name>]
|
||||
narratio config sources [--config <pipeline.yml>] [--campaign <id> | --campaign-file <campaign.yml>] [--profile <name>]
|
||||
narratio config diff <left-profile> <right-profile> [--config <pipeline.yml>] [--campaign <id> | --campaign-file <campaign.yml>]
|
||||
```
|
||||
|
||||
These commands resolve the selected profile, defaults, ordinary paths, and—if
|
||||
@@ -112,6 +113,27 @@ legacy-player, and generated family ownership. A generated party member has
|
||||
one family record and one party record at the same logical path. The output
|
||||
never reads or prints secret values.
|
||||
|
||||
`config diff` resolves both supplied profile names from one parsed root source
|
||||
set and compares their fully resolved, secret-free effective mappings. It does
|
||||
not accept `--profile`; the two positional names must be distinct, declared
|
||||
profiles. When party-driven families are present, both profiles must resolve to
|
||||
the same selected campaign and party. Use `--campaign-file` if profile-specific
|
||||
campaign configuration would otherwise select different files.
|
||||
|
||||
Equal profiles print `no differences`. Otherwise, sorted tab-separated records
|
||||
use one of these forms, with compact JSON values:
|
||||
|
||||
```text
|
||||
added <path> <right-value>
|
||||
removed <path> <left-value>
|
||||
changed <path> <left-value> <right-value>
|
||||
```
|
||||
|
||||
Mappings are flattened to their logical field paths; lists remain one atomic
|
||||
value. The command compares defaulted concrete artifacts and publish rules, not
|
||||
profile names, source-file layout, or formatting. It succeeds when differences
|
||||
are found, making it suitable for review and migration checks.
|
||||
|
||||
### `version`
|
||||
|
||||
```bash
|
||||
|
||||
@@ -48,6 +48,9 @@ the durable copied session input.
|
||||
sources` use the same `--config`, `--campaign`, `--campaign-file`, and
|
||||
`--profile` selection rules as pipeline commands, but do not select, discover,
|
||||
or load a session. They do not read credential values or create runtime state.
|
||||
`narratio config diff <left-profile> <right-profile>` uses the same pipeline and
|
||||
campaign selectors, resolves each named profile independently from one parsed
|
||||
root source set, and does not accept a separate `--profile` flag.
|
||||
|
||||
Campaign selection is optional only when the resolved pipeline has no
|
||||
`scriptorium.artifact_families`. When families are declared, Narratio selects a
|
||||
@@ -60,9 +63,17 @@ composition and family declarations omitted. `config sources` prints a stable
|
||||
source projection instead of effective values: root/import/profile/default
|
||||
ownership plus campaign/party and generated-family records. Canonical derived
|
||||
players trace to the party; a legacy configured players file is explicitly
|
||||
marked as a legacy player source. The [CLI reference](cli.md#config-validate-config-show-and-config-sources)
|
||||
marked as a legacy player source. The [CLI reference](cli.md#config-validate-config-show-config-sources-and-config-diff)
|
||||
owns command syntax and output conventions.
|
||||
|
||||
`config diff` compares normalized field values rather than YAML text or source
|
||||
ownership. It emits sorted `added`, `removed`, and `changed` records, uses
|
||||
compact deterministic JSON values, treats lists atomically, and reports `no
|
||||
differences` when the complete effective configurations are equal. Concrete
|
||||
family members and generated publish rules participate after expansion; moving
|
||||
an equal value between eligible root/import sources does not create a
|
||||
difference.
|
||||
|
||||
### Identity segments
|
||||
|
||||
Campaign IDs (`campaign_id` and `default_campaign_id`), session IDs, previous
|
||||
|
||||
@@ -53,7 +53,7 @@ a temporary downloaded session file therefore cannot invalidate the resolved
|
||||
pipeline or campaign context.
|
||||
|
||||
The application also has a separate read-only inspection resolver for `config
|
||||
validate` and `config show`. It uses the same production root/profile and
|
||||
validate`, `config show`, and `config sources`. It uses the same production root/profile and
|
||||
campaign selection functions, but never routes through session discovery,
|
||||
remote-session download, secret loading, adapter composition, workspace
|
||||
initialization, manifest access, or cleanup. A pipeline with retained artifact
|
||||
@@ -79,6 +79,17 @@ derived players point to the party source, while legacy players retain a
|
||||
dedicated legacy-player role. The application command only joins these sorted
|
||||
records with selection metadata and never reparses configuration files.
|
||||
|
||||
`config diff` uses a paired profile loader that parses the root, imports, and
|
||||
declared overlays once, then clones the additive base before independently
|
||||
selecting, decoding, defaulting, and finalizing each profile. When campaign
|
||||
resolution is needed, the command loads one selected campaign and party and
|
||||
expands both effective pipelines from that same party value. The configuration
|
||||
owner projects each normalized effective mapping into sorted logical paths;
|
||||
mapping leaves are compared individually while sequence values remain atomic.
|
||||
Values are compact deterministic JSON representations for command output, not
|
||||
raw YAML fragments, ownership records, or secret material. A differing digest
|
||||
with no projected difference is treated as an internal consistency error.
|
||||
|
||||
Campaign context construction also reads and classifies the campaign-owned
|
||||
party source through `ParseParty`. A canonical party retains its raw bytes and
|
||||
normalized roster in runtime-only `ResolvedParty` provenance, while a legacy
|
||||
|
||||
@@ -75,6 +75,14 @@ and effective configuration digest. Status distinguishes the current resolved
|
||||
value from the last value persisted in the session manifest, which helps
|
||||
diagnose profile switches without changing resume authority.
|
||||
|
||||
Before switching an operational profile, compare its effective meaning with the
|
||||
current selection through `narratio config diff <left-profile> <right-profile>`.
|
||||
The command is read-only and succeeds whether it finds differences or not. Its
|
||||
sorted records describe defaulted, expanded concrete configuration—not source
|
||||
file layout—so it can be used to review model, artifact, and publish changes
|
||||
without creating a session or run. Select the same campaign explicitly when
|
||||
profiles could resolve different campaign paths; see the [CLI reference](cli.md#config-validate-config-show-config-sources-and-config-diff) for syntax and record format.
|
||||
|
||||
## Stage Execution and Continuation Behavior
|
||||
|
||||
Canonical stage order:
|
||||
|
||||
@@ -1048,7 +1048,7 @@ generated configuration without leaking secrets or internal YAML machinery.
|
||||
|
||||
## Stage 19 — Semantic `config diff`
|
||||
|
||||
**Status: Pending**
|
||||
**Status: Completed**
|
||||
|
||||
### Goal
|
||||
|
||||
|
||||
Reference in New Issue
Block a user