# security-case-types tools Validator and renderer for SecurityCaseTypes and SecurityCases (`canon/standards/security-case-types_v0.1.md`, schemas `canon/schemas/security-case-type_v0.1.schema.json` and `security-case_v0.1.schema.json`). ```bash # a type directory: type.yaml, README.md sections, tests, example cases python3 tools/security-case-types/security_case_validator.py validate-type security-case-types/ # a case against its type (security-case-types//type.yaml) python3 tools/security-case-types/security_case_validator.py validate-case --types security-case-types # render a case into the composer's plan plus materialization, follow-through, # verification and rollback; execution is never permitted python3 tools/security-case-types/security_case_validator.py render \ --types security-case-types capabilities/playbooks/*.yaml ``` Only `implemented` types accept cases. `--allow-unimplemented` exists for a type's own example cases while the type is being written and acknowledged. The validator refuses, among other things: missing sections, unknown or unpinned capabilities, attended steps without justification, steps or materialized items without a rollback, verification without a negative check or that reads a value, templates with unknown parameters, credential-shaped values anywhere, secret parameters that are not custody references, and high-risk types without founder acceptance. To start a type: copy `security-case-types/_template/`, rename the directory to the type id, and rewrite every section. The template's tests travel with it: rename `tests/test_type.py` to `tests/test__contract.py` so module names stay unique. Tests: `python3 -m pytest tools/security-case-types/tests security-case-types/*/tests`. ## Explicit source versions The default --types root is unchanged. Select a separately acknowledged source version explicitly, without moving its package into the default root: ```bash python3 tools/security-case-types/security_case_validator.py validate-case \ security-case-type-revisions/1.2/oidc-browser-relying-party/examples/forgejo.yaml \ --types security-case-types \ --version-root 1.2=security-case-type-revisions/1.2 ``` This ordinary command refuses:1.2 is acknowledged, not implemented. For source-only preparation, the existing --allow-unimplemented option may be added; its render is deterministic and execution.permitted remains false. Current canonical1.1 is also acknowledged and its historical accepted case/normal refusal/preparation render remain exactly retained. No source acknowledgment or historical case acceptance is an implementation/native proof waiver. The Python API is load_type(default_root, exact_reference, version_roots={"1.2": explicit_root}). Each key must be an exact major.minor and each root a Path. CLI --version-root VERSION=PATH may repeat for DIFFERENT versions. A matching explicit version selects exactly one root; a missing/wrong/ambiguous source refuses without trying the default or another revision. Versions without a mapping continue using --types. No directory discovery, highest/latest selection, status promotion or automatic owner-adapter adoption occurs. Duplicate mappings (even identical), duplicate YAML fields, mismatched source ID/version, malformed/traversal references and selected symlinks refuse. Direct case validation also requires the case reference to match the supplied type ID/version. An explicit root is source input, not an owner acknowledgment or grant. Callers retain exact source hashes/type/case/render in their own reviewed receipts. Existing two-argument load_type callers, including ops-mason, retain their default behavior until their owner deliberately adopts the optional input. Adapter/global provenance/native first-reference gates remain separate in NK-WP-0048-T06 and the existing ORGREF driver. ## Check existing owner evidence compatibility The normal validator CLI now accepts `check-evidence` using the same exact type selection, declarations, validation and deterministic render as `render`: ```sh python3 tools/security-case-types/security_case_validator.py check-evidence \ security-cases/forgejo-netkingdom-oidc.yaml --types security-case-types \ --structure-request /path/to/mason-structure-request.json \ --warden-journal /path/to/existing/journal.sqlite ``` Normal admission still refuses the acknowledged 1.1 and 1.2 types. Explicit `--allow-unimplemented` permits source preparation, with the existing `--version-root 1.2=security-case-type-revisions/1.2` for that version. No owner protocol is automatically adopted, no journal is created, and no status changes. This is the cross-owner **compatibility preflight**, not native acceptance. It consumes the existing `ops-mason.case-structure-request.v1` and reads latest rows from the existing `warden.case.step-journal.v1` SQLite journal in read-only mode. Mason source/request hashes, complete current structural inventory and structural projection must match the fresh render. Warden case/type and type-declared machine descriptor pins, owners, bounded histories, created-object scope and successful attempt/revocation fingerprints must match. Unknown or duplicate fields, source substitution and missing completed-attempt fingerprints refuse. Running, uncertain, failed or rolled-back outcomes retain their exact meanings; an earlier success never overrides the latest journal row. Generated-value paths require distinct parent-session and broker-grant fingerprint fields. Exit 0 means these supplied artifacts are source-compatible; it never means the case is complete. No artifact is required solely to render missing gates. Output always has `native_complete: false`, `execution.permitted: false`, and explicit unresolved native gates. A Mason Request has no native Observation provenance; a Warden journal retains fingerprints rather than portable signed/native proof. This command deliberately offers no trust callback, native-success flag, dispatch or way to promote self-authored JSON into native evidence. Actual independent owner evidence admission, status-hash binding, accepted machine descriptors, delivery, human sign-in/consumer denial, revocation and created-only rollback remain NK-WP-0048-T06 owner integration work. It does not mark any type implemented. Integration tests invoke actual sibling Mason `prepare` and Warden `Journal.save` with metadata fixtures only. They need those owner source checkouts, and existing type suites need the public KeyCape request file and provider declarations beside the checkout. `NET_KINGDOM_ROOT` selects the source root for the 1.2 package tests.