Cross-Platform Contract Propagation Audit
Overview
Audit a contract change from its source through every transformation and consumer before release. Treat a field that exists in one schema as incomplete until its meaning, defaults, wire behavior, rollout controls, client handling, analytics, and tests are proven across all relevant paths.
This is a read-only evidence workflow. It reports propagation gaps; it does not implement them.
When to Use This Skill
- Use when adding or changing a field, enum value, status, capability, or feature flag shared by multiple components.
- Use when database, backend, API, Web, Android, iOS, jobs, events, or analytics may interpret the same value differently.
- Use when a change must preserve existing records, older clients, or a default-off rollout.
- Use when a change looks complete in one endpoint but may be missing from alternate entry points or generated models.
How It Works
Step 1: Write the semantic contract
Before tracing files, state the business invariant and define every observable state. Distinguish values that languages and serializers often collapse:
| State |
Questions to answer |
| missing |
Is the property absent on the wire or in an old record? |
null |
Is it unknown, inherited, unsupported, or invalid? |
false or zero |
Is this an explicit disabled value or a default? |
true or non-zero |
What behavior becomes available? |
| unknown enum |
Must old consumers ignore, preserve, or reject it? |
Record compatibility requirements, ownership, rollout condition, and the exact user-visible or system behavior for each state. Do not accept optional, nullable, and default false as equivalent without evidence.
Step 2: Enumerate the propagation graph
List every relevant node before judging completeness:
source of truth
-> persistence and migration
-> domain model and mapper
-> service or policy computation
-> every API, event, cache, and job projection
-> generated or handwritten client model
-> client state and presentation logic
-> analytics and operational observability
-> tests, rollout, and rollback checks
Include alternate read/write endpoints, list/detail projections, background consumers, offline caches, admin surfaces, older app versions, and feature-flag evaluation points when they are in scope. Mark a node not applicable only with a reason.
Step 3: Trace evidence edge by edge
For each edge, cite the producer, transformation, consumer, and test using file paths, symbols, schema names, or other inspectable evidence. Assign one status:
| Status |
Meaning |
proven |
Producer and consumer agree, with direct evidence and relevant test coverage. |
partial |
Some paths or states agree, but coverage is incomplete. |
missing |
A required propagation edge or consumer is absent. |
conflict |
Two layers implement different semantics. |
unknown |
Evidence is unavailable or ambiguous. |
not_applicable |
The layer is outside scope, with a stated reason. |
Do not upgrade likely, convention, type compatibility, or a framework default to proven. A declaration proves shape, not runtime mapping or behavior.
Step 4: Check the high-risk boundaries
Inspect these boundaries explicitly:
- Migration and existing data: default, backfill, nullability, rollback, mixed-version reads and writes.
- Domain mapping: missing/null coercion, enum fallbacks, validation, derived values, serialization symmetry.
- Fan-out surfaces: list and detail DTOs, events, caches, jobs, search indexes, SDKs, and alternate API versions.
- Client compatibility: missing and explicit-null decoding, unknown enums, generated-model drift, cached payloads, release or minified builds.
- Rollout control: flag default, evaluation location, cohort consistency, kill switch, and behavior when stored data disagrees with the flag.
- Analytics: offered, rendered, attempted, succeeded, and failed events carry enough contract and version context to join reliably.
Step 5: Build a state-by-path test matrix
Cross the semantic states from Step 1 with every material path from Step 2. At minimum, include existing-data defaults, enabled and disabled values, flag on and off, alternate endpoints, current clients, and representative older clients.
For each cell, record the expected result, evidence, and status. A unit test at one layer does not prove an end-to-end cell. Use unknown for unexecuted cells.
Step 6: Decide against explicit release gates
Derive gates from the stated contract, not from intuition. A release is blocked when an edge or compatibility invariant that the contract explicitly requires is missing, conflict, or unknown, or when rollback cannot contain the new behavior. Use inconclusive only when the release contract itself is absent or ambiguous, so the audit cannot determine which edges or invariants are required. Do not downgrade a
1---2name: cross-platform-contract-propagation-audit3description: Use when auditing whether a field, enum, flag, or API contract propagates consistently across storage, services, clients, analytics, and tests.4---5
6
7# Cross-Platform Contract Propagation Audit
8
9## Overview
10
11Audit a contract change from its source through every transformation and consumer before release. Treat a field that exists in one schema as incomplete until its meaning, defaults, wire behavior, rollout controls, client handling, analytics, and tests are proven across all relevant paths.
12
13This is a read-only evidence workflow. It reports propagation gaps; it does not implement them.
14
15## When to Use This Skill
16
17- Use when adding or changing a field, enum value, status, capability, or feature flag shared by multiple components.
18- Use when database, backend, API, Web, Android, iOS, jobs, events, or analytics may interpret the same value differently.
19- Use when a change must preserve existing records, older clients, or a default-off rollout.
20- Use when a change looks complete in one endpoint but may be missing from alternate entry points or generated models.
21
22## How It Works
23
24### Step 1: Write the semantic contract
25
26Before tracing files, state the business invariant and define every observable state. Distinguish values that languages and serializers often collapse:
27
28| State | Questions to answer |
29|---|---|
30| missing | Is the property absent on the wire or in an old record? |
31| `null` | Is it unknown, inherited, unsupported, or invalid? |
32| `false` or zero | Is this an explicit disabled value or a default? |
33| `true` or non-zero | What behavior becomes available? |
34| unknown enum | Must old consumers ignore, preserve, or reject it? |
35
36Record compatibility requirements, ownership, rollout condition, and the exact user-visible or system behavior for each state. Do not accept `optional`, `nullable`, and `default false` as equivalent without evidence.
37
38### Step 2: Enumerate the propagation graph
39
40List every relevant node before judging completeness:
41
42```text
43source of truth
44 -> persistence and migration
45 -> domain model and mapper
46 -> service or policy computation
47 -> every API, event, cache, and job projection
48 -> generated or handwritten client model
49 -> client state and presentation logic
50 -> analytics and operational observability
51 -> tests, rollout, and rollback checks
52```
53
54Include alternate read/write endpoints, list/detail projections, background consumers, offline caches, admin surfaces, older app versions, and feature-flag evaluation points when they are in scope. Mark a node `not applicable` only with a reason.
55
56### Step 3: Trace evidence edge by edge
57
58For each edge, cite the producer, transformation, consumer, and test using file paths, symbols, schema names, or other inspectable evidence. Assign one status:
59
60| Status | Meaning |
61|---|---|
62| `proven` | Producer and consumer agree, with direct evidence and relevant test coverage. |
63| `partial` | Some paths or states agree, but coverage is incomplete. |
64| `missing` | A required propagation edge or consumer is absent. |
65| `conflict` | Two layers implement different semantics. |
66| `unknown` | Evidence is unavailable or ambiguous. |
67| `not_applicable` | The layer is outside scope, with a stated reason. |
68
69Do not upgrade `likely`, convention, type compatibility, or a framework default to `proven`. A declaration proves shape, not runtime mapping or behavior.
70
71### Step 4: Check the high-risk boundaries
72
73Inspect these boundaries explicitly:
74
75- **Migration and existing data:** default, backfill, nullability, rollback, mixed-version reads and writes.
76- **Domain mapping:** missing/null coercion, enum fallbacks, validation, derived values, serialization symmetry.
77- **Fan-out surfaces:** list and detail DTOs, events, caches, jobs, search indexes, SDKs, and alternate API versions.
78- **Client compatibility:** missing and explicit-null decoding, unknown enums, generated-model drift, cached payloads, release or minified builds.
79- **Rollout control:** flag default, evaluation location, cohort consistency, kill switch, and behavior when stored data disagrees with the flag.
80- **Analytics:** offered, rendered, attempted, succeeded, and failed events carry enough contract and version context to join reliably.
81
82### Step 5: Build a state-by-path test matrix
83
84Cross the semantic states from Step 1 with every material path from Step 2. At minimum, include existing-data defaults, enabled and disabled values, flag on and off, alternate endpoints, current clients, and representative older clients.
85
86For each cell, record the expected result, evidence, and status. A unit test at one layer does not prove an end-to-end cell. Use `unknown` for unexecuted cells.
87
88### Step 6: Decide against explicit release gates
89
90Derive gates from the stated contract, not from intuition. A release is blocked when an edge or compatibility invariant that the contract explicitly requires is `missing`, `conflict`, or `unknown`, or when rollback cannot contain the new behavior. Use `inconclusive` only when the release contract itself is absent or ambiguous, so the audit cannot determine which edges or invariants are required. Do not downgrade a