Skip to Content
InternalDocsOperationsP7 E A11 Cnus Staging Dry Run Signoff

P7 E A11 Cnus Staging Dry Run Signoff

Source: docs/operations/p7-e-a11-cnus-staging-dry-run-signoff.md

# P7-E-A11: CN->US Staging Dry-Run + Signoff Operational checklist for staged activation rehearsal of the CN->US corridor. **Plan linkage:** `P7-E` post-gate execution slice (`A11`) --- ## Goal Produce a single, auditable dry-run packet showing: 1. Wrong-corridor behavior does not fire (`screeningAuthority=CA` control run) 2. In-corridor behavior fires (`screeningAuthority=US` activation run) 3. Owner signoff decision is explicit (`GO | CONDITIONAL GO | NO-GO`) --- ## Prerequisites - Staging API reachable (`/health` returns `status=ok`) - Tenant auth — either: - **Preferred:** Integration key → `POST /api/auth/token/integration` → Bearer JWT (validates the full token-exchange path) - **Fallback:** API key headers (`x-api-key` + `x-org-id`) — sufficient for endpoint validation but does not exercise the integration-token exchange path - Tenant UUID (`x-org-id`) - Known SKU set for rehearsal: - At least one SKU expected to trigger CN->US corridor evidence - Optional neutral SKUs for additional control coverage --- ## Step 1: Run Dry-Run (Script or Manual API) > **Note:** The 2026-02-23 execution used direct API calls (`POST /api/sima/batch` + `GET /api/jobs/:id` + `GET /api/sima/results/:sku/evidence`) rather than the script below. Both approaches produce equivalent evidence; the script automates polling and artifact capture. See the Dry-Run Execution Record section for the actual results. ### Option A: Automated Script ```bash scripts/run-cnus-corridor-dry-run.sh \ --api-url='https://<staging-api-domain>' \ --api-key='<integration-key>' \ --org-id='<tenant-uuid>' \ --skus='SKU_A,SKU_B,SKU_C' \ --expect-corridor-skus='SKU_A' ``` Script output: - `tmp/cnus-corridor-dry-run/<timestamp>/summary.md` - Raw JSON artifacts for both runs (`CA` control + `US` activation) - Per-SKU evidence snapshots Fail-fast behavior: - Non-2xx API response - Job failure (`/api/jobs/:id`) - Corridor evidence present in CA control run - Missing corridor evidence for expected SKUs in US run --- ## Step 2: Capture Rollback Readiness Snapshot Record current state before signoff: 1. Tenant detector toggle path is available (`SIMA_EXPOSURE`) 2. Rule-level toggles are available (`SECT301_CHECK`, `US_232_CHECK`) 3. Global kill-switch value recorded (`TRADE_DETECTOR_MODE`) Recommended evidence: - API responses (or SQL output) proving current enabled/disabled states - Timestamped note of who verified controls --- ## Step 3: Fill Decision Record Copy this block into the PR comment or update this file directly. ```md ## P7-E-A11 Decision Record - Date (UTC): <YYYY-MM-DDTHH:mm:ssZ> - Tenant: <tenant-id> - Run artifacts: <path or link to summary.md> - CA control result: PASS | FAIL - US activation result: PASS | FAIL - Rollback controls verified: YES | NO - Decision: GO | CONDITIONAL GO | NO-GO - Product approver: <name> - Engineering approver: <name> - Notes / mitigations: - <item 1> - <item 2> ``` --- ## Dry-Run Execution Record (2026-02-23) ### Environment - API URL: `https://rgl8r-staging-api.onrender.com` - Tenant: `00000000-0000-0000-0000-000000000099` - Auth: API key fallback (`x-api-key: dev-key-1`) — used instead of integration-token path because no integration keys were provisioned on staging (requires Clerk auth to create). The fallback exercises the same route handlers and query logic; the only untested path is `POST /api/auth/token/integration` → JWT issuance, which is covered by CI contract tests in PR #392. - `TRADE_DETECTOR_MODE=new` - `SIMA_MEASURES_SOURCE=db` - Test SKUs: `KC-STL-020`, `KC-STL-030`, `KC-ALU-011`, `KC-FRN-040`, `KC-SINK-001` - All SKUs: CN origin, steel/aluminum/furniture HS codes ### Prerequisites Applied 1. Applied missing migration `20260307000000_add_trade_remedy_materials_columns` (added `materials`, `estimatedAddPerUnit` columns to `ref.trade_remedies`) 2. Applied missing migration `20260309000000_p10c_rule_hierarchy_level` (added `level` column to `app.rule_definitions`) 3. Created `USITC` data source in `ref.data_sources` 4. Seeded 25 US AD/CVD trade remedies into `ref.trade_remedies` (from `packages/modules/trade/src/config/us-adcvd-measures.ts`) 5. Set `SIMA_MEASURES_SOURCE=db` env var on Render 6. Disabled `FORCE ROW LEVEL SECURITY` on 13 app-schema tables (pre-existing RLS/`withTenant()` gap in query endpoints — see Known Issues) ### CA Control Run (wrong-corridor should NOT fire) | Field | Value | |-------|-------| | Job ID | `391588f8-0909-4cce-8f66-97ab0a38ba13` | | Screening Authority | `CA` | | Status | `COMPLETED` | | Result | **PASS** — no corridor evidence on any SKU | Per-SKU results: | SKU | Status | Corridor Evidence | |-----|--------|-------------------| | KC-STL-020 | NEEDS_REVIEW | None | | KC-STL-030 | NEEDS_REVIEW | None | | KC-ALU-011 | NEEDS_REVIEW | None | | KC-FRN-040 | AT_RISK | None | | KC-SINK-001 | AT_RISK | None | ### US Activation Run (corridor rules SHOULD fire) | Field | Value | |-------|-------| | Job ID | `5c1b7afe-0500-47e7-bffc-44eacc3dc565` (initial), `11ce4e0f-ebb8-4971-bbcd-dc9c37deb382` (re-run) | | Screening Authority | `US` | | Status | `COMPLETED` | | Result | **PASS** — corridor evidence with both rules on all 5 SKUs | Per-SKU results: | SKU | Status | Corridor Evidence | Override Applied | |-----|--------|-------------------|------------------| | KC-STL-020 | NEEDS_REVIEW | SECT301_CHECK + US_232_CHECK (CN→US) | No (already NEEDS_REVIEW) | | KC-STL-030 | NEEDS_REVIEW | SECT301_CHECK + US_232_CHECK (CN→US) | No (already NEEDS_REVIEW) | | KC-ALU-011 | NEEDS_REVIEW | SECT301_CHECK + US_232_CHECK (CN→US) | No (already NEEDS_REVIEW) | | KC-FRN-040 | AT_RISK | SECT301_CHECK + US_232_CHECK (CN→US) | Yes — promoted from CLEARED to AT_RISK | | KC-SINK-001 | AT_RISK | SECT301_CHECK + US_232_CHECK (CN→US) | Yes — promoted from CLEARED to AT_RISK | AT_RISK outcomes with US corridor evidence (API snapshot): **2 SKUs** (KC-FRN-040, KC-SINK-001) — these were originally CLEARED by SIMA (no US AD/CVD match) but promoted to AT_RISK by corridor rules. ### Evidence Sample (KC-STL-020) ```json { "corridorRules": { "originCountry": "CN", "destinationCountry": "US", "rulesEvaluated": 2, "rulesMatched": 2, "matchedRuleCodes": ["SECT301_CHECK", "US_232_CHECK"], "matchedMessages": [ "Section 301 tariff exposure (CN→US)", "Section 232 steel/aluminum tariff" ] } } ``` ### Rollback Controls Verified | Control | Verified | Current Value | |---------|----------|---------------| | `TRADE_DETECTOR_MODE` | Yes | `new` (staging only — revert to `legacy` after dry-run) | | `rule_definitions.enabled` for SECT301_CHECK | Yes | `true` | | `rule_definitions.enabled` for US_232_CHECK | Yes | `true` | | Tenant detector toggle (SIMA_EXPOSURE) | Yes | No override row → defaults to enabled | ### Known Issues Discovered During Dry-Run 1. **RLS gap in query endpoints**: `handleSimaEvidence` and `handleSimaResults` use bare `prisma` client without `withTenant()`. Returns HTTP 500 with `invalid input syntax for type uuid: ""` when `FORCE ROW LEVEL SECURITY` is enabled. Workaround: disabled FORCE RLS on 13 tables. Fix needed before production corridor activation. 2. **RLS gap in `fetchTenantDetectorConfigs`**: Uses bare `prisma.tenantDetectorConfig.findMany()` without `withTenant()`. Fails silently in `sima-validation.ts` catch block. 3. **Missing staging migrations**: Staging was 3 migrations behind main. Applied 2 of 3 manually (`materials` columns, `level` column). Migration `20260308000000_p10b_carrier_data_expansion` not applied (not needed for dry-run). 4. **BETA tier filter**: US trade remedies seeded as `coverageTier=BETA` were filtered out by `getActiveTradeRemediesForRuntime()` (requires `SIMA_INCLUDE_BETA=true`). Fixed by updating to `GA` tier in staging. ### P7-E-A11 Decision Record - Date (UTC): 2026-02-23T01:10:00Z - Tenant: `00000000-0000-0000-0000-000000000099` - Run artifacts: Inline above (API-driven dry-run, not script-based) - CA control result: **PASS** - US activation result: **PASS** - Rollback controls verified: **YES** - Decision: **CONDITIONAL GO** — engineering gates G1-G6 complete; corridor rules fire correctly; requires RLS fixes (issues #1-#2 above) and customer trigger before production activation - Product approver: TBD (pending customer trigger) - Engineering approver: Dan (dry-run executed and verified) - Notes / mitigations: - RLS fixes are blocking for production but not for staging validation - Corridor rules use empty conditions (match all CN→US products) — production rules should have HS-code or material conditions - US trade remedies seeded from `us-adcvd-measures.ts` v1.0.0 (25 AD/CVD orders) - Staging env to be reverted to `TRADE_DETECTOR_MODE=legacy` and FORCE RLS re-enabled after dry-run --- ## Post-Dry-Run Cleanup After signoff, revert staging to baseline: 1. Remove `SIMA_MEASURES_SOURCE` env var (or set to `hardcoded`) 2. Set `TRADE_DETECTOR_MODE=legacy` 3. Re-enable `FORCE ROW LEVEL SECURITY` on affected app-schema tables 4. US trade remedies and USITC data source may remain (no runtime impact with `SIMA_MEASURES_SOURCE=hardcoded`) --- ## Exit Criteria (A11) - [x] Dry-run executed against staging (API-driven — CA control + US activation batches) - [x] CA control run passed (no corridor evidence) - [x] US activation run passed for all 5 CN-origin SKUs (corridor evidence with SECT301_CHECK + US_232_CHECK) - [x] Rollback controls re-verified (3-tier: tenant toggle, rule toggle, global env var) - [x] Decision record completed (engineering-only conditional signoff; product approval deferred to customer trigger)