GitHub

Outcomes CLI Reference

Reference for nwave-ai outcomes register | check | check-delta. For learning the workflow, see the Your First Outcome tutorial. For triaging a collision, see the How-to resolve a collision.

Synopsis

nwave-ai outcomes [--registry PATH] register --id OUT-ID --kind KIND \
                                              --input-shape SHAPE \
                                              --output-shape SHAPE \
                                              [--summary STR] \
                                              [--feature STR] \
                                              [--keywords CSV] \
                                              [--artifact PATH]

nwave-ai outcomes [--registry PATH] check --input-shape SHAPE \
                                          --output-shape SHAPE \
                                          [--keywords CSV]

nwave-ai outcomes [--registry PATH] check-delta DELTA_PATH

Global options

Flag Default Description
--registry docs/product/outcomes/registry.yaml Path to the registry YAML file.

If the registry path does not exist, register and check create an empty skeleton (schema_version: "0.1", outcomes: []) before proceeding. check-delta does the same.

Verdict matrix

The detector runs two tiers and combines them into a verdict.

Tier-1 (shape match) Tier-2 Jaccard ≥ 0.4 Verdict Exit code
Yes Yes COLLISION 1
Yes No AMBIGUOUS 1
No Yes AMBIGUOUS 1
No No clean 0
  • Tier-1 = exact normalized match on (input_shape, output_shape) tuple. High precision on identical-intent duplicates.
  • Tier-2 = Jaccard similarity over tokenized keyword sets. Threshold 0.4. Disambiguates same-shape-different-intent cases.

nwave-ai outcomes register

Register a new outcome in the registry.

Synopsis

nwave-ai outcomes register --id OUT-ID --kind KIND \
                           --input-shape SHAPE --output-shape SHAPE \
                           [--summary STR] [--feature STR] \
                           [--keywords CSV] [--artifact PATH]

Flags

Flag Required Type Description
--id yes string Stable identifier matching ^OUT-[A-Z0-9-]+$ (e.g. OUT-E3, OUT-FORMAT).
--kind yes enum One of specification, operation, invariant.
--input-shape yes string Type expression for the input contract (e.g. FeatureDeltaModel).
--output-shape yes string Type expression for the output contract (e.g. tuple[Violation, ...]).
--summary no string One-line description. Default: empty string.
--feature no string Owning feature name. Default: unknown.
--keywords no CSV Comma-separated lowercase tokens (max 6). Default: empty.
--artifact no string Repo-relative path to the implementing artifact. Default: empty string.

Exit codes

Code Condition
0 Outcome registered successfully.
2 Duplicate --id (already in registry), or invalid Outcome (schema).

Output

stdout on success:

REGISTERED: OUT-MY-FIRST

stderr on failure:

ERROR: <error description>

Example

nwave-ai outcomes register \
  --id OUT-E6 \
  --kind specification \
  --input-shape FeatureDeltaModel \
  --output-shape "tuple[ValidationViolation, ...]" \
  --summary "Validate invocation_limits field shape" \
  --feature unified-feature-delta \
  --keywords "invocation,limits,validate,field,shape" \
  --artifact nwave_ai/feature_delta/domain/rules/e6_invocation_limits.py

Idempotency: registration is not idempotent on re-run. Calling register twice with the same --id exits 2.


nwave-ai outcomes check

Check a candidate outcome against the registry without registering it.

Synopsis

nwave-ai outcomes check --input-shape SHAPE --output-shape SHAPE \
                        [--keywords CSV]

Flags

Flag Required Type Description
--input-shape yes string Candidate's input shape.
--output-shape yes string Candidate's output shape.
--keywords no CSV Candidate's keywords (used for Tier-2). Default: ``.

Exit codes

Code Condition
0 No collisions detected (clean).
1 One or more collisions detected.

Output

stdout when clean:

NO COLLISIONS

stdout when collisions detected: one line per matched OUT-id, in registration order:

COLLISION: OUT-E3 (Tier-1 + Tier-2 0.67)
COLLISION: OUT-FORMAT (Tier-1 + Tier-2 0.50)
AMBIGUOUS: OUT-E3 (Tier-1 only)
AMBIGUOUS: OUT-E1 (Tier-2 0.45 only)

The label (COLLISION / AMBIGUOUS) reflects the overall verdict; the parenthetical annotation lists which tier(s) fired and the Jaccard score where applicable.

Examples

Tier-1 + Tier-2 hit:

nwave-ai outcomes check \
  --input-shape FeatureDeltaModel \
  --output-shape "tuple[ValidationViolation, ...]" \
  --keywords "non-empty,required,column"
# → exit 1
# → COLLISION: OUT-E3 (Tier-1 + Tier-2 0.67)

Same shape, different intent (Tier-1 only):

nwave-ai outcomes check \
  --input-shape FeatureDeltaModel \
  --output-shape "tuple[ValidationViolation, ...]" \
  --keywords "cherry-pick,row-count,ddd"
# → exit 1
# → AMBIGUOUS: OUT-E3 (Tier-1 only)

Clean candidate:

nwave-ai outcomes check \
  --input-shape int \
  --output-shape bool \
  --keywords "totally,different"
# → exit 0
# → NO COLLISIONS

nwave-ai outcomes check-delta

Aggregate scan: parse OUT-<id> references from a feature-delta.md and run a self-excluding collision check on each.

Synopsis

nwave-ai outcomes check-delta DELTA_PATH

Positional arguments

Argument Required Type Description
delta_path yes path Path to the feature-delta.md file.

Exit codes

Code Condition
0 Zero collisions across all referenced OUT-ids.
1 One or more referenced OUT-ids collide with another entry.
2 delta_path does not exist.

Output

stdout aggregate report (always):

3 outcomes checked, 1 collision found across 1 outcome
  COLLISION: OUT-E3

stdout warning when an OUT-id is referenced in the delta but missing from the registry:

WARNING: OUT-E99 referenced in delta but not in registry

stderr on missing delta file:

ERROR: feature-delta not found: <path>

How OUT-ids are extracted

The CLI scans delta_path text for the regex \bOUT-[A-Z0-9-]+\b and processes each unique match in document order. There is no semantic parsing of section headings; if your delta references OUT-E3 in prose, it is checked.

Self-exclusion

When the CLI checks OUT-E3, it excludes OUT-E3 itself from the snapshot. Otherwise every registered outcome would trivially collide with itself.

Example

nwave-ai outcomes check-delta docs/feature/my-feature/feature-delta.md
# → exit 1
# → 3 outcomes checked, 1 collision found across 1 outcome
# →   COLLISION: OUT-E3

Registry schema

The registry file is YAML matching the JSON Schema at docs/product/outcomes/schema.json (draft-07). Each entry is one element of the top-level outcomes: list.

Top-level structure

schema_version: "0.1"
outcomes:
  - id: OUT-...
    kind: specification | operation | invariant
    summary: <string>
    feature: <string>
    inputs:
      - shape: <string>
    output:
      shape: <string>
    keywords: [<token>, ...]
    artifact: <path>
    related: [<OUT-id>, ...]
    superseded_by: <OUT-id> | null

Field reference

Field Type Required Constraint / Notes
id string yes Pattern ^OUT-[A-Z0-9-]+$.
kind enum yes One of specification, operation, invariant.
summary string yes Free-form, one-line description.
feature string yes Feature name owning the outcome.
inputs array yes At least one {shape: <string>} entry. Currently a single shape used.
output object yes Single {shape: <string>} entry.
keywords array yes ≤ 6 tokens; each matches ^[a-z0-9][a-z0-9-]*$. May be empty.
artifact string yes Repo-relative path to the implementation. May be empty.
related array yes OUT-ids declaring "intentional non-collision". May be empty.
superseded_by string|null yes OUT-id replacing this outcome, or null.

additionalProperties is false — unrecognized keys cause a schema validation error.

Canonical order

Outcomes are written in registration order (newest at the bottom). Within an entry, fields appear in the order shown above.


Shape normalization

Tier-1 matches normalized shape strings, not raw user input. The normalizer:

  • strips leading and trailing whitespace,
  • strips parameter names from tuple shapes — (name: T, ...)(T, ...),
  • preserves type alias differences (Path and str are not automatically equated; that is reserved for v2 with an opt-in flag).

Practical implication: (text: str, file_path: str) and (str, str) normalize to the same string and Tier-1-collide. Path and str do not.


Keyword tokenization

Tier-2 tokenizes keywords as follows:

  • Lowercase.
  • Split on -, _, and whitespace.
  • Drop tokens of length ≤ 2.
  • Treat result as a set; compute Jaccard similarity |A ∩ B| / |A ∪ B|.

Threshold: ≥ 0.4 → Tier-2 fires.


Common error messages

Stderr Cause Fix
ERROR: duplicate id: OUT-X register --id OUT-X and OUT-X already in registry. Pick a different id, or use the existing entry.
ERROR: <validation message> Outcome fails schema validation (e.g. malformed id, kind). Fix the offending field.
ERROR: feature-delta not found: <path> check-delta given a path that does not exist. Pass a real feature-delta.md path.
WARNING: OUT-X referenced in delta but not in registry Delta references an OUT-id you have not registered. Register it, or remove the reference.