Contextual Allow-Only Contracts¶
Contextual allow-only contracts restrict a discovered (role, metadata) selector match's
references to an explicit allowed list of (role, metadata) selectors — whitelist semantics,
matching the existing allow_only family's shape but comparing discovered role/metadata directly
instead of resolving through a declared layers.<name>.
Groups:
strict_context_allow_onlyaudit_context_allow_only
See Contextual dependency contracts for the shared selector shape and
metadata operator vocabulary (exact, any, in, not-equal-to-source) — both contextual
families use the identical selector grammar.
Example¶
contracts:
strict_context_allow_only:
- id: sales-allow-only
name: sales-may-depend-only-on-own-context
source:
role: DomainLayer
metadata:
domain: Sales
allowed:
- role: DomainLayer
metadata:
domain: Sales
- role: SharedKernel
reason: Sales may depend only on its own context or the shared kernel.
A type matching source may reference only types matching allowed; any other reference is a
violation.
Fields¶
| Field | Required | Meaning |
|---|---|---|
name |
yes | Human-readable contract name. |
id |
no | Stable identifier for --contract, baselines, and ignored-violation matching. |
source |
yes | A contextual selector matched against candidate source types. |
allowed |
yes, non-empty | A list of contextual selectors; a source-matching type's reference to any non-matching, role-classified target is a violation. |
exclude |
no | A list of contextual selectors; a candidate target matching any entry is removed from consideration before allowed-list evaluation and before ignored_violations. |
ignored_violations |
no | Same shape and semantics as the existing allow_only family. |
reason |
no | Human-readable rationale surfaced in diagnostics and generated baselines. |
Only role-classified referenced types are considered violation candidates — an unclassified
type (framework/BCL types, primitives, etc.) can never match any selector and is not reported,
mirroring how the existing allow_only family only considers references already inside a declared
layer.
CEL predicates¶
Contextual source/allowed/exclude selectors accept an optional when
field, evaluated the same way as the context_dependencies family: additive
to literal role/metadata, with allowed[*].when/exclude[*].when
compiling against a context schema declaring source, target, and
dependency so an allowed selector can restrict targets to the same
context as their source:
contracts:
strict_context_allow_only:
- name: sales-same-domain-only
source:
role: Domain
allowed:
- role: Domain
when: target.metadataText["domain"] == source.metadataText["domain"]
reason: Sales may only depend on its own domain.
The rule stays the same as everywhere else in the model: existing selector
fields remain literal and only an explicit when field carries a CEL
predicate. A when evaluation failure fails the run as a policy/configuration
error — for both strict_context_allow_only and audit_context_allow_only —
rather than being treated as a non-match, and is never suppressed by
baseline. When no allowed selector matches but one came close (its literal
role/metadata matched and only when evaluated false), the violation's
evidence names that near-miss expression.
dependency is reserved, not usable, in this release — see the
identical note in
Contextual dependency contracts; the
same fail-closed rejection applies here for allowed[*].when/exclude[*].when.
Exclude vs. allowed vs. ignored_violations¶
Three mechanisms interact, applied in this order:
exclude— a pre-match filter; an excluded candidate is never evaluated againstallowedat all.allowed— a candidate survivingexcludethat matches noallowedselector is a violation.ignored_violations— post-violation suppression, keyed on concrete source/target type names.
Diagnostics¶
A contextual allow-only violation's diagnostic carries the source type's resolved role and metadata
and the target type's resolved role and metadata — evidence a namespace/layer allow_only violation
does not carry. Human output tags the finding (kind: context_allow_only, ...); JSON/CI-artifact
output includes source_role, source_metadata, target_role, and target_metadata fields.
Strict vs. audit¶
Same semantics as every other family: strict_context_allow_only fails the build,
audit_context_allow_only reports without failing (the CLI process itself still exits non-zero for
audit findings under --mode audit — see Exit codes).
Baselines¶
strict_context_allow_only/audit_context_allow_only participate in baseline generation, merge,
and comparison identically to the allow_only family — see
Migration baselines.