feat: add universal resource activation policy profile flow

This commit is contained in:
defiQUG
2026-04-24 22:06:26 -07:00
parent 0035a787fe
commit 566cecd8f9
71 changed files with 2705 additions and 153 deletions

View File

@@ -21,5 +21,9 @@ jobs:
REMOTE="${GITEA_WORKFLOW_REMOTE:-gitea}"
fi
git fetch --depth=1 "$REMOTE" main master
# Optional: set org/repo variable URA_STRICT_CLOSURE=1 to fail PRs while pilot placeholders
# remain in manifest (see scripts/ura/validate-manifest-closure.mjs). Not enabled by default.
- name: run-all-validation (no LAN, no genesis)
env:
URA_STRICT_CLOSURE: ${{ vars.URA_STRICT_CLOSURE }}
run: bash scripts/verify/run-all-validation.sh --skip-genesis

View File

@@ -21,5 +21,9 @@ jobs:
REMOTE="${GITEA_WORKFLOW_REMOTE:-gitea}"
fi
git fetch --depth=1 "$REMOTE" main master
# Optional: set org/repo variable URA_STRICT_CLOSURE=1 to fail PRs while pilot placeholders
# remain in manifest (see scripts/ura/validate-manifest-closure.mjs). Not enabled by default.
- name: run-all-validation (no LAN, no genesis)
env:
URA_STRICT_CLOSURE: ${{ vars.URA_STRICT_CLOSURE }}
run: bash scripts/verify/run-all-validation.sh --skip-genesis

View File

@@ -0,0 +1,44 @@
{
"schemaVersion": "1.0.0",
"updatedAt": "2026-04-25T18:00:00Z",
"description": "Canonical jurisdiction catalog for multi-institution onboarding. Add rows as jurisdictions are formally in-scope. Legal review required before marking status production_ready.",
"jurisdictions": [
{
"id": "ID",
"label": "Indonesia",
"governingLawNote": "Indonesian law; BI and sector regulators — detail in compliance matrix, not legal advice.",
"regulatorsNote": "Bank Indonesia (BI); OJK where applicable — confirm with counsel.",
"activitiesInScope": ["payments_omnl", "server_funds_treasury", "rtgs_sidecars", "chain138_settlement_evidence"],
"activitiesExcluded": ["generic_securities_issuance_unless_scoped"],
"complianceMatrixPath": "docs/04-configuration/compliance-matrices/ID-INDONESIA/banking_v1.md",
"status": "pilot_ready",
"policyProfileIdsReferenced": [
"institutional_custody_skr_v1",
"server_funds_treasury_v1",
"infra_capacity_ops_v1"
]
},
{
"id": "GENERIC-COMMON-LAW-STUB",
"label": "Generic common-law banking stub (template)",
"governingLawNote": "Illustrative only — replace with real jurisdiction before production.",
"regulatorsNote": "Placeholder — no regulator list.",
"activitiesInScope": ["template_process_only"],
"activitiesExcluded": ["all_production_until_replaced"],
"complianceMatrixPath": "docs/04-configuration/compliance-matrices/GENERIC-COMMON-LAW-STUB/banking_v1.md",
"status": "template_only",
"policyProfileIdsReferenced": []
},
{
"id": "US-DELAWARE-CORP-STUB",
"label": "US Delaware corporate stub (draft second jurisdiction)",
"governingLawNote": "Illustrative corporate/treasury stub — not legal advice; replace with real federal/state matrix.",
"regulatorsNote": "Placeholder.",
"activitiesInScope": ["draft_matrix_training_only"],
"activitiesExcluded": ["all_production_until_replaced"],
"complianceMatrixPath": "docs/04-configuration/compliance-matrices/US-DELAWARE-CORP-STUB/banking_v1.md",
"status": "draft",
"policyProfileIdsReferenced": []
}
]
}

View File

@@ -0,0 +1,70 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://d-bis.org/schemas/universal-resource-activation.policy-profile-registry.v1.json",
"title": "PolicyProfileRegistry",
"type": "object",
"required": ["schemaVersion", "profiles"],
"properties": {
"schemaVersion": { "type": "string", "minLength": 1 },
"updatedAt": { "type": "string" },
"description": { "type": "string" },
"profiles": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"policyProfileId",
"version",
"jurisdictions",
"participantClasses",
"resourceFamilies",
"minimumGruGovernanceLevel"
],
"properties": {
"policyProfileId": { "type": "string", "minLength": 1 },
"version": { "type": "string", "minLength": 1 },
"effectiveFrom": { "type": "string" },
"effectiveTo": { "type": "string" },
"supersedes": { "type": "string" },
"jurisdictions": {
"type": "array",
"minItems": 1,
"items": { "type": "string" }
},
"participantClasses": {
"type": "array",
"minItems": 1,
"items": { "type": "string" }
},
"resourceFamilies": {
"type": "array",
"minItems": 1,
"items": { "type": "string" }
},
"tokenizationModesAllowed": {
"type": "array",
"items": { "type": "string" }
},
"ledgerModel": { "type": "string" },
"standards": {
"type": "array",
"items": { "type": "string" }
},
"minimumGruGovernanceLevel": {
"type": "integer",
"minimum": 0,
"maximum": 5
},
"complianceMatrixPaths": {
"type": "array",
"items": { "type": "string" }
},
"notes": { "type": "string" }
},
"additionalProperties": true
}
}
},
"additionalProperties": true
}

View File

@@ -0,0 +1,36 @@
# URA manifest — automation design
**Last updated:** 2026-04-25
**Status:** **Implemented in-repo:** fragment merge + strict closure gate + public Phoenix read for `policy-profiles.json` + ledger/settlement fragment CLIs + [`URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md`](../../docs/04-configuration/universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md). Full OMNL ETL and GRU M00 diamond remain **operator/service** work; standalone `PolicyProfileRegistry` ships under `smom-dbis-138/contracts/universal-resource/`.
## Implemented
| Piece | Location |
|-------|----------|
| Merge fragments → validated manifest | `scripts/ura/merge-manifest-fragments.mjs` · `pnpm ura:merge-manifest` |
| Shared schema validation | `scripts/ura/lib/validate-ura-manifest.mjs` (used by `pnpm ura:validate` and merge) |
| Production placeholder gate | `scripts/ura/validate-manifest-closure.mjs` · `pnpm ura:validate-closure` (warn) / `pnpm ura:validate-closure:strict` (fail) · optional `URA_STRICT_CLOSURE=1` in `validate-config-files.sh` |
| Fragment drop zone | `manifest-fragments/README.md` |
| Public API: policy profiles | `GET /api/v1/universal-resource-activation/policy-profiles` on phoenix-deploy-api |
## Goals (remaining / service-bound)
- Generate fragments from **approved** ops forms, ledger exports, chain receipts (outside this repo or future ETL).
- Fail CI on **production** branches when closure rules violate (use `URA_STRICT_CLOSURE=1` on that pipeline).
## Pipeline (merge)
1. **Inputs:** JSON fragments under `manifest-fragments/*.json` (or another `--fragments-dir`).
2. **Merge:** Deterministic sort; `policyProfileRefs` union; resources/evidence by id with shallow merge.
3. **Validate:** Full JSON Schema + cross-checks (`validateUraManifestData`).
4. **Optional:** `--out path` to write; then review and replace `manifest.json` if intended.
## Non-goals
- Automatic legal classification of assets (human sign-off on matrices + profiles).
- Writing to chain or OMNL from this repo without separate deployment controls.
## Related
- [`UNIVERSAL_RESOURCE_WIRING.md`](../../docs/04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md)
- [`scripts/validate/validate-ura-policy-profiles.mjs`](../../scripts/validate/validate-ura-policy-profiles.mjs)

View File

@@ -0,0 +1,23 @@
# Policy profiles registry — doc control
**Last updated:** 2026-04-25
**Purpose:** Human-readable **change control** for rows in [`policy-profiles.json`](policy-profiles.json). Legal/risk owns interpretation; engineering owns schema conformance (`pnpm ura:validate-profiles`).
| `policyProfileId` | Version in registry | `effectiveFrom` | Legal / risk sign-off | Notes |
|-------------------|---------------------|-----------------|----------------------|-------|
| `institutional_custody_skr_v1` | 1 | 2026-04-25 | Pending — replace when signed | ID matrix: SKR / custody path |
| `server_funds_treasury_v1` | 1 | 2026-04-25 | Pending — replace when signed | ID matrix: server funds / OMNL |
| `infra_capacity_ops_v1` | 1 | 2026-04-25 | Pending — replace when signed | LAN internal capacity |
## Procedure
1. Add or bump `version` and `effectiveFrom` in `policy-profiles.json`; update this table with sign-off reference (ticket, memo id, or “N/A — internal only”).
2. Ensure [`manifest.json`](manifest.json) `policyProfileRefs` lists every profile used by a resource at the correct version.
3. Run `pnpm ura:validate && pnpm ura:validate-profiles`.
## Related
- [`UNIVERSAL_RESOURCE_POLICY_PROFILES.md`](../../docs/04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_POLICY_PROFILES.md)
- [`DBIS_RAIL_JURISDICTION_TRACEABILITY.md`](../../docs/dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md)
- **Public read:** `GET /api/v1/universal-resource-activation/policy-profiles` on phoenix-deploy-api (same auth rules as manifest; override via `UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH`).
- **On-chain anchor (optional):** `smom-dbis-138/contracts/universal-resource/PolicyProfileRegistry.sol` — publish `contentHash` from `pnpm ura:profile-hash <policyProfileId>`; see [`GRU_REGISTRY_WIRING_CHECKLIST.md`](../../docs/runbooks/GRU_REGISTRY_WIRING_CHECKLIST.md) §6.

View File

@@ -0,0 +1,8 @@
{
"journalEntryId": "OMNL-JE-2026-00042",
"batchRef": "FINERACT-BATCH-88",
"postedAt": "2026-04-25T12:00:00Z",
"currency": "USD",
"amountMinor": "1000000",
"notes": "Illustrative export shape — replace with real OMNL/Fineract field names from your deployment."
}

View File

@@ -0,0 +1,10 @@
{
"schemaVersion": "1.0.0",
"description": "Example mapping from Fineract/OMNL export fields to URA evidence package columns. Copy to omnl-ledger-mapping.v1.json when live.",
"evidencePackages": [
{
"evidencePackageId": "ura:pilot:evidence-register-bootstrap",
"accountingRefField": "journalEntryId"
}
]
}

View File

@@ -0,0 +1,48 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://d-bis.org/schemas/omnl-ledger-mapping.v1.json",
"title": "OMNLLedgerMapping",
"type": "object",
"required": ["schemaVersion", "evidencePackages"],
"properties": {
"schemaVersion": { "type": "string", "const": "1.0.0" },
"description": { "type": "string" },
"resourceUpdates": {
"type": "array",
"items": {
"type": "object",
"required": ["resourceId", "quantityField"],
"properties": {
"resourceId": { "type": "string", "minLength": 1 },
"quantityField": { "type": "string", "description": "Dot path in ledger snapshot for quantity string" }
},
"additionalProperties": false
}
},
"evidencePackages": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["evidencePackageId"],
"properties": {
"evidencePackageId": { "type": "string", "minLength": 1 },
"accountingRefField": {
"type": "string",
"description": "Dot path into ledger snapshot JSON for accountingRef string (e.g. journalEntryId or omnl.batchRef)"
},
"quantityField": {
"type": "string",
"description": "Optional dot path for resource quantity string"
},
"resourceIdForQuantity": {
"type": "string",
"description": "If quantityField set, which resource row to patch"
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}

View File

@@ -0,0 +1,38 @@
# URA manifest fragments (optional)
**Purpose:** Drop partial JSON files here to **merge** onto the canonical [`../manifest.json`](../manifest.json) without hand-editing the full file. Used for ops overlays, environment-specific rows, or generated snippets.
## Fragment shape
Each `*.json` file (sorted by filename; skip `_prefix.json`) may contain any of:
| Key | Effect |
|-----|--------|
| `policyProfileRefs` | Union with manifest (same `id` + `version` deduped). |
| `resources` | Add or **shallow-merge** replace by `resourceId`. |
| `evidencePackages` | Add or **shallow-merge** replace by `evidencePackageId`. |
Top-level manifest fields (`schemaVersion`, `description`, …) come **only** from the `--base` file (default: `manifest.json`).
## Commands
```bash
pnpm ura:merge-manifest
# Validate merge and print counts (dry-run; does not write)
node scripts/ura/merge-manifest-fragments.mjs --out /tmp/merged.json
# Write merged JSON; inspect and copy into manifest.json if correct
```
After any manifest edit: `pnpm ura:validate && pnpm ura:validate-profiles`.
## Production gate
When pilots are closed, enforce no placeholders:
```bash
pnpm ura:validate-closure:strict
# Or: URA_STRICT_CLOSURE=1 bash scripts/validation/validate-config-files.sh
```
See [`MANIFEST_AUTOMATION_DESIGN.md`](../MANIFEST_AUTOMATION_DESIGN.md) and [`URA_PILOT_CLOSURE_RUNBOOK.md`](../../../docs/04-configuration/universal-resource-activation/URA_PILOT_CLOSURE_RUNBOOK.md).

View File

@@ -1,7 +1,7 @@
{
"schemaVersion": "1.0.0",
"updatedAt": "2026-04-24T00:00:00Z",
"description": "Canonical in-repo store for universal resource activation (SKR, server funds, infra). Replace example-* rows in production; keep valid JSON and run scripts/validate/validate-universal-resource-activation.mjs in CI.",
"updatedAt": "2026-04-25T12:00:00Z",
"description": "Canonical in-repo store for universal resource activation (SKR, server funds, infra). Pilot-scoped resourceIds; jurisdiction ID for financial pilots per JURISDICTION_CATALOG and ID-INDONESIA matrix. Replace ura:participant:pilot-*-assign and evidence TBDs per URA_PILOT_CLOSURE_RUNBOOK.md. Run pnpm ura:validate && pnpm ura:validate-profiles in CI.",
"policyProfileRefs": [
{ "id": "institutional_custody_skr_v1", "version": "1" },
{ "id": "server_funds_treasury_v1", "version": "1" },
@@ -9,14 +9,14 @@
],
"resources": [
{
"resourceId": "ura:example:skr-pilot-placeholder",
"resourceId": "ura:pilot-1:skr-custody-record",
"schemaVersion": 1,
"displayName": "Example SKR / custody position (pilot template)",
"description": "Replace with a real safekeeping or strategic evidence-backed record. Not production.",
"displayName": "Pilot 1 — SKR / custody record",
"description": "PILOT-1 (Indonesia-scope): bind participant registry id, evidenceRefs, and custody evidence per URA_PILOT_CLOSURE_RUNBOOK.md and ID-INDONESIA compliance matrix.",
"family": "SKR_SAFEKEEPING",
"subType": "CUSTODY_STATEMENT",
"ownerParticipantId": "0x0000000000000000000000000000000000000000000000000000000000000000",
"jurisdiction": "TBD",
"ownerParticipantId": "ura:participant:pilot-1-assign",
"jurisdiction": "ID",
"policyProfileId": "institutional_custody_skr_v1",
"tokenizationMode": "NONE",
"quantity": "0",
@@ -25,17 +25,17 @@
"encumbranceState": "unencumbered",
"lifecycleState": "draft",
"deployabilityState": "informational_only",
"evidenceRefs": []
"evidenceRefs": ["ura:evidence:pending-pilot-1-custody-package"]
},
{
"resourceId": "ura:example:server-funds-pilot",
"resourceId": "ura:pilot-2:server-funds-treasury-pool",
"schemaVersion": 1,
"displayName": "Example server funds pool (pilot template)",
"description": "Logical funding resource; bind to OMNL/Fineract and server-funds-sidecar when SoR is frozen. Not a wallet balance.",
"displayName": "Pilot 2 — Server funds treasury pool",
"description": "PILOT-2 (Indonesia-scope): OMNL + server-funds-sidecar SoR; replace accountingRef in evidence when ledger posts per runbook.",
"family": "SERVER_FUNDS",
"subType": "TREASURY_POOL",
"ownerParticipantId": "0x0000000000000000000000000000000000000000000000000000000000000000",
"jurisdiction": "TBD",
"ownerParticipantId": "ura:participant:pilot-2-assign",
"jurisdiction": "ID",
"policyProfileId": "server_funds_treasury_v1",
"tokenizationMode": "NONE",
"quantity": "0",
@@ -44,16 +44,16 @@
"encumbranceState": "unencumbered",
"lifecycleState": "draft",
"deployabilityState": "funding_eligible",
"evidenceRefs": []
"evidenceRefs": ["ura:evidence:pending-pilot-2-ledger-link"]
},
{
"resourceId": "ura:example:infra-r630-01-capacity",
"resourceId": "ura:pilot-3:infra-r630-01-api-small",
"schemaVersion": 1,
"displayName": "Example R630-01 capacity slice (pilot template)",
"description": "Operational capacity record; not a tradable security. See reports/storage and ALL_VMIDS_ENDPOINTS for live inventory.",
"displayName": "Pilot 3 — Infra capacity (R630-01, api_small)",
"description": "PILOT-3: LAN ops capacity; link deploymentRef in evidence after non-prod deploy per runbook.",
"family": "INFRA_CAPACITY",
"subType": "BUNDLE",
"ownerParticipantId": "0x0000000000000000000000000000000000000000000000000000000000000000",
"ownerParticipantId": "ura:participant:pilot-3-assign",
"jurisdiction": "LAN",
"policyProfileId": "infra_capacity_ops_v1",
"tokenizationMode": "NONE",
@@ -62,22 +62,26 @@
"encumbranceState": "unencumbered",
"lifecycleState": "active",
"deployabilityState": "infra_allocatable",
"evidenceRefs": []
"evidenceRefs": ["ura:evidence:pending-pilot-3-capacity-verify"]
}
],
"evidencePackages": [
{
"evidencePackageId": "ura:example:evidence-ura-bootstrap",
"evidencePackageId": "ura:pilot:evidence-register-bootstrap",
"resourceIds": [
"ura:example:skr-pilot-placeholder",
"ura:example:server-funds-pilot",
"ura:example:infra-r630-01-capacity"
"ura:pilot-1:skr-custody-record",
"ura:pilot-2:server-funds-treasury-pool",
"ura:pilot-3:infra-r630-01-api-small"
],
"actionType": "REGISTER",
"initiator": "repo_bootstrap",
"timestamp": "2026-04-24T00:00:00Z",
"reconciliationStatus": "matched",
"explanation": "Bootstrap example package linking the three template resources; replace with real packages per UNIVERSAL_RESOURCE_PILOT_PLAN.md"
"initiator": "pilot_bootstrap",
"timestamp": "2026-04-25T12:00:00Z",
"reconciliationStatus": "open",
"custodyOrSourceEvidence": "PILOT-1: TBD — custodian statement or attestation hash per UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md; remove when real ref linked.",
"accountingRef": "PILOT-2: TBD — OMNL/Fineract journal or batch id when server-funds path posts (see URA_PILOT_CLOSURE_RUNBOOK.md).",
"settlementOrChainRef": "PILOT-2/3: TBD — MintAuth messageId / tx hash / rail ref per DBIS_RAIL_TECHNICAL_SPEC_V1.md when settlement leg exists.",
"deploymentRef": "PILOT-3: TBD — VMID, FQDN, health URL after deploy per UNIVERSAL_RESOURCE_PILOT_PLAN.md.",
"explanation": "REGISTER package binding three pilots. Set reconciliationStatus to matched only after mandatory joins per UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md and jurisdiction matrix rows."
}
]
}

View File

@@ -0,0 +1,53 @@
{
"schemaVersion": "1.0.0",
"updatedAt": "2026-04-25T00:00:00Z",
"description": "Machine-readable URA policy profile registry. Manifest policyProfileRefs must reference ids listed here. See UNIVERSAL_RESOURCE_POLICY_PROFILES.md and compliance-matrices/.",
"profiles": [
{
"policyProfileId": "institutional_custody_skr_v1",
"version": "1",
"effectiveFrom": "2026-04-25",
"jurisdictions": ["*", "ID"],
"participantClasses": ["institutional", "sovereign"],
"resourceFamilies": ["SKR_SAFEKEEPING", "STRATEGIC_RECORD"],
"tokenizationModesAllowed": ["NONE", "CLAIM", "ENTITLEMENT"],
"ledgerModel": "off_chain_omnl",
"standards": ["ISO20022_LOGGING"],
"minimumGruGovernanceLevel": 2,
"complianceMatrixPaths": [
"docs/04-configuration/compliance-matrices/ID-INDONESIA/banking_v1.md"
],
"notes": "SKR / custody evidence-backed; conservative transfer defaults per policy doc."
},
{
"policyProfileId": "server_funds_treasury_v1",
"version": "1",
"effectiveFrom": "2026-04-25",
"jurisdictions": ["*", "ID"],
"participantClasses": ["institutional", "sovereign"],
"resourceFamilies": ["SERVER_FUNDS"],
"tokenizationModesAllowed": ["NONE"],
"ledgerModel": "hybrid",
"standards": ["ISO20022_LOGGING", "TRAVEL_RULE"],
"minimumGruGovernanceLevel": 3,
"complianceMatrixPaths": [
"docs/04-configuration/compliance-matrices/ID-INDONESIA/banking_v1.md"
],
"notes": "Good-funds, GL mapping, holds/releases; Rail settlement when on-chain leg used."
},
{
"policyProfileId": "infra_capacity_ops_v1",
"version": "1",
"effectiveFrom": "2026-04-25",
"jurisdictions": ["*", "LAN"],
"participantClasses": ["institutional", "internal_ops"],
"resourceFamilies": ["INFRA_CAPACITY"],
"tokenizationModesAllowed": ["NONE", "ENTITLEMENT"],
"ledgerModel": "off_chain_omnl",
"standards": ["IPSAS"],
"minimumGruGovernanceLevel": 1,
"complianceMatrixPaths": [],
"notes": "Internal capacity; not a traded security by default."
}
]
}

View File

@@ -65,6 +65,7 @@
## Related artifacts
- [DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md](DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md) — workstreams and exit criteria aligned to this matrix (multi-jurisdiction master plan execution).
- [dbis_chain_138_technical_master_plan.md](../../dbis_chain_138_technical_master_plan.md)
- [docs/00-meta/TODO_TASK_LIST_MASTER.md](../00-meta/TODO_TASK_LIST_MASTER.md)
- [docs/03-deployment/DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md](DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md)

View File

@@ -0,0 +1,90 @@
# DBIS RTGS — master plan implementation tracker
**Last updated:** 2026-04-25
**Purpose:** Executable tracker mapping the **multi-jurisdiction institutional onboarding master plan** to [DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md) rows and slice-1 scope ([SLICE1_SCOPE_FREEZE.md](../04-configuration/jurisdictions/SLICE1_SCOPE_FREEZE.md)). **Status here is documentation of intent;** the canonical component status remains the E2E matrix until rows are updated there.
## How to use
1. Pick a **workstream** below.
2. Execute engineering / ops tasks until **exit criteria** match the matrix rows **Production gate** column.
3. Update **DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md** `Current state` to `Complete` (or `Retired` with rationale).
4. Link evidence to URA packages per [ID-INDONESIA/banking_v1.md](../04-configuration/compliance-matrices/ID-INDONESIA/banking_v1.md) where applicable.
---
## Workstream W1 — Canonical OMNL / Fineract rail
| Matrix rows (indicative) | OMNL / Fineract API rail; Mifos X frontend / tenant |
|--------------------------|-----------------------------------------------------|
| **Exit criteria** | Tenant and operator rail **frozen**; reproducible posting, office/GL mapping, reconciliation package path. |
| **Owner** | OMNL / banking ops |
| **URA link** | `SERVER_FUNDS` resources get real `accountingRef`; [URA_PILOT_CLOSURE_RUNBOOK.md](../04-configuration/universal-resource-activation/URA_PILOT_CLOSURE_RUNBOOK.md) pilot 2. |
## Workstream W2 — `server-funds-sidecar`
| Matrix rows | `server-funds-sidecar` (VMID 5803) |
|-------------|-------------------------------------|
| **Exit criteria** | Treasury SoR boundaries frozen; **draw / hold / release** validated with auth; Phoenix `SERVER_FUNDS_SIDECAR_URL` set in prod. |
| **Owner** | HYBX integration lead |
| **URA link** | Pilot 2; [UNIVERSAL_RESOURCE_WIRING.md](../04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md) probe returns 200. |
## Workstream W3 — `off-ledger-2-on-ledger-sidecar`
| Matrix rows | Off-ledger → Chain 138 settlement |
|-------------|-----------------------------------|
| **Exit criteria** | Canonical event → settlement **end-to-end** with durable evidence; finality handling closed. |
| **Owner** | HYBX + Chain 138 settlement lead |
| **URA link** | `settlementOrChainRef` in evidence packages. |
## Workstream W4 — ISO 20022 + institutional 4.995 package
| Matrix rows | ISO evidence and vault path; Institutional 4.995 package path |
|-------------|---------------------------------------------------------------|
| **Exit criteria** | `--strict` or institution-agreed readiness; reproducible archive/hash path. |
| **Owner** | Regulatory / compliance + eng |
| **Compliance link** | [INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md](../04-configuration/mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md) |
## Workstream W5 — Indonesia BNI domestic path
| Matrix rows | Indonesia / BNI domestic banking path |
|-------------|----------------------------------------|
| **Exit criteria** | Live endpoint/auth/message contract **or** explicit deferral documented in matrix + jurisdiction matrix. |
| **Owner** | Indonesia banking integration lead |
| **Compliance link** | [DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md) |
## Workstream W6 — Global correspondent path
| Matrix rows | Global correspondent / liquidity bank path |
|-------------|---------------------------------------------|
| **Exit criteria** | Same as matrix production gate; cross-border flow validated **or** out of slice 1. |
| **Owner** | Cross-border banking integration lead |
## Workstream W7 — Identity stack (Fabric / Indy / Aries)
| Matrix rows | Fabric, Indy, Aries, AnonCreds, etc. |
|-------------|--------------------------------------|
| **Exit criteria** | **Scope decision** in/out slice 1; if out, matrix shows Planned/Retired without production claims. |
| **Owner** | Identity architecture lead |
## Workstream W8 — Depository / custody / securities
| Matrix rows | Depository, global custodian, securities-sidecar, custody flow |
|-------------|----------------------------------------------------------------|
| **Exit criteria** | Canonical lifecycle documented + one path validated **or** deferred with rationale. |
| **Owner** | Custody / securities architecture leads |
| **URA link** | Pilot 1 SKR; policy profile `institutional_custody_skr_v1`. |
## Workstream W9 — RTGS production gate
| Matrix rows | RTGS production gate row |
|-------------|--------------------------|
| **Exit criteria** | All **mandatory** rows for **chosen architecture** = `Complete`. |
| **Owner** | DBIS program owner |
---
## Related
- [DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md)
- [DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md](DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md)
- [INSTITUTION_ONBOARDING_CHARTER.md](../04-configuration/compliance-matrices/INSTITUTION_ONBOARDING_CHARTER.md)

View File

@@ -0,0 +1,63 @@
# URA manifest writer — operations
**Last updated:** 2026-04-25
**Purpose:** Runbook for **ledger- and chain-driven** manifest updates: secrets, ETL, publish path, reconciliation, optional features, legal record, DR.
## 1. Components
| Piece | Role |
|-------|------|
| OMNL / Fineract | System of record for `accountingRef` (journal / batch ids). |
| Server-funds sidecar | Operational draws/holds; must correlate to ledger lines. |
| [`build-ledger-fragment.mjs`](../../scripts/ura/manifest-writer/build-ledger-fragment.mjs) | Maps export JSON → manifest fragment. |
| [`merge-manifest-fragments.mjs`](../../scripts/ura/merge-manifest-fragments.mjs) | Merges fragments; validates. |
| Phoenix | Serves canonical [`manifest.json`](../../config/universal-resource-activation/manifest.json) read-only. |
## 2. Fineract / OMNL field inventory
**Operator task:** Document the **exact** REST or batch export fields your deployment uses (tenant, office, product). Map them in [`omnl-ledger-mapping.v1.example.json`](../../config/universal-resource-activation/integration/omnl-ledger-mapping.v1.example.json) (copy to `omnl-ledger-mapping.v1.json`).
Minimum: one stable string for `accountingRef` (journal id or composite `officeId:transactionId`).
## 3. Secrets and IAM
- Store Fineract credentials in vault / `.env` on the writer host (never in git).
- Use read-only Fineract user where possible.
- Rotate keys on the same cadence as OMNL operator policy.
## 4. Publish path (choose one)
| Mode | Pattern |
|------|---------|
| **Git PR** | Writer opens PR updating `manifest.json` or a fragment; CI runs `pnpm ura:validate`. |
| **Secured sync** | Writer writes to `PHOENIX_REPO_ROOT` on deploy host; reload Phoenix. |
| **Authenticated API** | Future: POST internal-only (not the public GET routes). |
## 5. Reconciliation
- Nightly (or per batch): compare latest Fineract journal id set to manifest `accountingRef`.
- On mismatch: page on-call; do **not** auto-overwrite without human ack for production.
## 6. Optional features
- **Real-time:** Webhook from Fineract vs **batch** cron — feature-flag in writer.
- **Multi-pool:** Multiple rows in `resourceUpdates` / evidence mapping file.
- **DLQ:** Failed merges land in a queue path for replay.
- **Audit log:** Append-only log of fragment bytes + git SHA + operator id.
## 7. Legal sign-off record
When automation goes live, archive:
- Compliance memo id or ticket referencing matrix rows satisfied by automated fields.
- Version of [`policy-profiles.json`](../../config/universal-resource-activation/policy-profiles.json) and [`ID-INDONESIA/banking_v1.md`](../04-configuration/compliance-matrices/ID-INDONESIA/banking_v1.md) (or relevant matrix).
## 8. DR and rollback
- **Backup:** Git history of `manifest.json` + weekly object-store copy if using direct sync.
- **Rollback:** Revert commit or restore file; re-run `pnpm ura:validate && pnpm ura:validate-profiles`.
- **Incident:** Disable writer cron/systemd; serve last known-good manifest from Phoenix override path.
## Related
- [`URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md`](../04-configuration/universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -93,9 +93,17 @@ This directory contains setup and configuration guides.
- **[DBIS Rail Control Mapping v1](../dbis-rail/DBIS_RAIL_CONTROL_MAPPING_V1.md)** ⭐⭐ - Control IDs mapped to checklist, Spec, Rulebook, and Threat Model for audit and SOC 2 / ISO 27001 alignment.
- **[DBIS Rail and Project Completion Master v1](../dbis-rail/DBIS_RAIL_AND_PROJECT_COMPLETION_MASTER_V1.md)** ⭐⭐ - Project and deployment status; full task list (required and optional) for DBIS Rail and project completion.
**Multi-jurisdiction institutional onboarding (master plan artifacts):**
- **[compliance-matrices/README.md](compliance-matrices/README.md)** — Per-jurisdiction matrices, template, Indonesia + generic stub.
- **[compliance-matrices/INSTITUTION_ONBOARDING_CHARTER.md](compliance-matrices/INSTITUTION_ONBOARDING_CHARTER.md)** — RACI and definition of Complete.
- **[compliance-matrices/INSTITUTION_ONBOARDING_PLAYBOOK.md](compliance-matrices/INSTITUTION_ONBOARDING_PLAYBOOK.md)** — Repeatable onboarding steps.
- **[jurisdictions/JURISDICTION_CATALOG.md](jurisdictions/JURISDICTION_CATALOG.md)**, **[jurisdictions/SLICE1_SCOPE_FREEZE.md](jurisdictions/SLICE1_SCOPE_FREEZE.md)** — Catalog + slice-1 scope; machine: [`config/jurisdictions/catalog.v1.json`](../../config/jurisdictions/catalog.v1.json).
- **[../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md)** — Rail controls ↔ jurisdiction matrices ↔ profiles.
**Universal resource activation (SKR, server funds, infra capacity):**
- **[universal-resource-activation/README.md](universal-resource-activation/README.md)** ⭐⭐ — Ontology, policy profiles, lanes, pilots, JSON Schemas, in-repo [`manifest.json`](../../config/universal-resource-activation/manifest.json), `node scripts/validate/validate-universal-resource-activation.mjs`, Phoenix `GET /api/v1/universal-resource-activation/manifest`.
- **[universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md](universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md)** — Operator wiring: env (`UNIVERSAL_RESOURCE_MANIFEST_PATH`), CI, API resolution order.
- **[universal-resource-activation/README.md](universal-resource-activation/README.md)** ⭐⭐ — Ontology, policy profiles, lanes, pilots, [`manifest.json`](../../config/universal-resource-activation/manifest.json), [`policy-profiles.json`](../../config/universal-resource-activation/policy-profiles.json); `pnpm ura:validate`, `pnpm ura:validate-profiles`, `pnpm ura:keccak`, `pnpm ura:smoke` (`--http` + `PHOENIX_BASE_URL`). Phoenix: `GET /api/v1/universal-resource-activation/manifest`, `GET /api/v1/universal-resource-activation/server-funds-sidecar-probe`. [MASTER_INDEX.md](../MASTER_INDEX.md) §04-configuration.
- **[universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md](universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md)** — Operator wiring: `UNIVERSAL_RESOURCE_MANIFEST_PATH`, `SERVER_FUNDS_SIDECAR_URL`, CI, testing checklist.
- **RTGS execution tracker:** [../03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md](../03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md).
- **[Implementation coordination (transcript 540ae663)](../dbis-rail/IMPLEMENTATION_COORDINATION_WITH_TRANSCRIPT_540AE663.md)** ⭐⭐ - Coordinate implementations with PMM/DEX, tokens, GRU, cW*, deployments; maps Completion Master tasks to done/partial/open.
- **[DBIS Rail Ledger Attestation Add-On v1.5](../dbis-rail/DBIS_RAIL_LEDGER_ATTESTATION_ADDON_V1_5.md)** ⭐⭐ - LPA state machine, reversal matrix, signer effectiveFromBlock/revokedAtBlock mandatory.
- **[DBIS Rail Conversion Router Spec v1.5](../dbis-rail/DBIS_RAIL_CONVERSION_ROUTER_SPEC_V1_5.md)** ⭐⭐ - SwapAuth, best execution/MEV, quote provenance, venue allowlist, sanctions/AML for swaps.

View File

@@ -0,0 +1,9 @@
# GENERIC-COMMON-LAW-STUB — template only
**Status:** template_only — **not** for production institutions.
Use this folder to practice matrix structure before copying [_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md](../_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md) to a real jurisdiction code.
| File | Purpose |
|------|---------|
| [banking_v1.md](banking_v1.md) | Illustrative obligation rows |

View File

@@ -0,0 +1,36 @@
# Compliance matrix — GENERIC-COMMON-LAW-STUB — banking_v1 (ILLUSTRATIVE ONLY)
**Last updated:** 2026-04-25
**Status:** **template_only** — do **not** use for production institutions. Copy [../_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md](../_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md) and replace with a real jurisdiction.
**Purpose:** Train the onboarding process: obligation rows, control linkage, evidence columns.
---
## 1. Law / regulation inventory (fictional placeholders)
| Ref id | Short title | Scope | Notes |
|--------|-------------|-------|-------|
| STUB-BANK-001 | Illustrative banking supervision act | banking | Fictional — replace with real citations. |
| STUB-AML-001 | Illustrative AML law | AML | Fictional. |
---
## 2. Requirement and control mapping (illustrative rows)
| Matrix row id | Obligation summary | Participant classes | URA family | Enforcement | Control ids | Evidence expectation |
|---------------|-------------------|---------------------|------------|-------------|-------------|----------------------|
| STUB-001 | Illustrative: know your customer for institutional treasury | institutional | `SERVER_FUNDS` | off-chain | C7, STUB-KYB-001 | Onboarding file + audit log reference |
| STUB-002 | Illustrative: sanctions screening before funding draw | institutional | `SERVER_FUNDS` | hybrid | C7, STUB-SAN-001 | Screening vendor ref + timestamp in evidence package |
| STUB-003 | Illustrative: safekeeping evidence for custody record | institutional | `SKR_SAFEKEEPING` | off-chain | C9, STUB-CUST-001 | Custodian statement hash in `custodyOrSourceEvidence` |
---
## 3. Residual risk
All rows are **non-binding** examples. Production matrices require **counsel-approved** law inventory and signed control mapping.
## Related
- [JURISDICTION_CATALOG.md](../../jurisdictions/JURISDICTION_CATALOG.md)
- [ID-INDONESIA/banking_v1.md](../ID-INDONESIA/banking_v1.md) — real pilot jurisdiction example in this repo.

View File

@@ -0,0 +1,11 @@
# Indonesia (ID) — compliance matrices
**Status:** pilot_ready (counsel must validate legal inventory in `banking_v1.md`)
| File | Regime / topic |
|------|----------------|
| [banking_v1.md](banking_v1.md) | Banking, OMNL, sidecars, Rail, ISO / 4.995, BNI path |
**Catalog:** [`config/jurisdictions/catalog.v1.json`](../../../config/jurisdictions/catalog.v1.json) — `id: "ID"`
**Related:** [INSTITUTION_ONBOARDING_PLAYBOOK.md](../INSTITUTION_ONBOARDING_PLAYBOOK.md), [DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](../../../03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md)

View File

@@ -0,0 +1,59 @@
# Compliance matrix — Indonesia (ID) — banking_v1
**Last updated:** 2026-04-25
**Jurisdiction id:** ID
**Status:** **pilot_ready** — consolidate scattered repo guidance; **counsel must validate** all legal citations and obligation text before production claims.
**Machine-readable catalog:** [`config/jurisdictions/catalog.v1.json`](../../../config/jurisdictions/catalog.v1.json)
---
## 1. Law / regulation inventory (outline — verify with counsel)
| Ref id | Short title | Scope | Repo anchor (non-legal) |
|--------|-------------|-------|-------------------------|
| ID-BI-PAYMENT | BI payment system / RTGS-related rules (confirm scope) | banking, payments | [DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](../../../03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md), Indonesia rows |
| ID-OJK-SEC | OJK capital markets rules (if securities path in scope) | securities | Depository / securities sidecar rows in same matrix |
| ID-AML-CTF | AML / CTF obligations (confirm statutes) | AML | [DBIS_RAIL_RULEBOOK_V1.md](../../../dbis-rail/DBIS_RAIL_RULEBOOK_V1.md) good-funds / compliance alignment |
| ID-DP | Data protection (confirm PDP / sector rules) | data | Evidence vault / ISO path |
*Replace summaries with counsel-approved citations and effective dates.*
---
## 2. Requirement and control mapping (starter rows)
| Matrix row id | Obligation summary | Participant classes | URA family | Enforcement | Control ids | Evidence expectation |
|---------------|-------------------|---------------------|------------|-------------|-------------|----------------------|
| ID-OMNL-001 | Institutional ledger / OMNL posting path for RTGS slice | institutional | `SERVER_FUNDS` | off-chain | C8, C9, C17 | Deterministic `accountingRef`; JE / package per [OMNL_JOURNAL_LEDGER_MATRIX.md](../../mifos-omnl-central-bank/OMNL_JOURNAL_LEDGER_MATRIX.md) |
| ID-SIDECAR-001 | Server-funds treasury orchestration aligned with good-funds policy | institutional | `SERVER_FUNDS` | hybrid | C17, C12 | Sidecar draw/hold/release + evidence package; Phoenix probe [UNIVERSAL_RESOURCE_WIRING.md](../../universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md) |
| ID-RAIL-001 | On-chain settlement evidence (MintAuth / messageId) when rail used | institutional | `SERVER_FUNDS`, `FIAT_DIGITAL` (if applicable) | on-chain | C1C6, C10 | `settlementOrChainRef` per [DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md) |
| ID-ISO-001 | ISO 20022 / institutional evidence packaging | institutional | all lanes | off-chain | C9 | [INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md](../../mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md), matrix ISO row |
| ID-BNI-001 | Domestic bank partner connectivity (when BNI path in scope) | institutional | payments | off-chain | — | [DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](../../../03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md); freeze endpoint/auth |
| ID-SKR-001 | Custody / safekeeping evidence for SKR pilot | institutional | `SKR_SAFEKEEPING` | off-chain | C9 | `custodyOrSourceEvidence`, `evidenceRefs` on resource |
---
## 3. Deep links (implementation)
- HYBX operator: [HYBX_BATCH_001_OPERATOR_CHECKLIST.md](../../mifos-omnl-central-bank/HYBX_BATCH_001_OPERATOR_CHECKLIST.md)
- RTGS checklist: [DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](../../../03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md)
- Rail controls: [DBIS_RAIL_CONTROL_MAPPING_V1.md](../../../dbis-rail/DBIS_RAIL_CONTROL_MAPPING_V1.md)
- Traceability: [DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../../../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md)
---
## 4. Residual risk / exceptions
| Topic | Decision | Owner |
|-------|----------|-------|
| BNI live contract | Planned until live endpoint/auth evidenced — see RTGS matrix | Indonesia banking integration lead |
| Securities / CSD | Planned unless explicitly in slice 1 | Securities architecture lead |
---
## Document control
| Version | Date | Change |
|---------|------|--------|
| 0.1 | 2026-04-25 | Initial Indonesia banking_v1 matrix from master plan |

View File

@@ -0,0 +1,47 @@
# Institution onboarding charter — multi-jurisdiction compliance program
**Last updated:** 2026-04-25
**Purpose:** Governance for onboarding **institutions** under explicit **jurisdictions**, aligned with the multi-jurisdiction master plan (policy profiles, per-jurisdiction compliance matrices, RTGS/Rail evidence, URA).
**Do not treat this document as legal advice.** Counsel owns interpretation of statutes and regulations; this charter defines **roles, artifacts, and “complete”** for program execution.
---
## Definitions
| Term | Meaning |
|------|---------|
| **Institution** | Licensed or contracted participant (bank, CSD, treasury entity, program operator) using DBIS RTGS / Rail / URA artifacts. |
| **Jurisdiction** | Legal regime under which the institution operates for a given activity (may be multiple per institution). |
| **Policy profile** | Versioned ruleset referenced by `policyProfileId` on URA resources — see [UNIVERSAL_RESOURCE_POLICY_PROFILES.md](../universal-resource-activation/UNIVERSAL_RESOURCE_POLICY_PROFILES.md) and [policy-profiles.json](../../../config/universal-resource-activation/policy-profiles.json). |
| **Compliance matrix** | Per-jurisdiction mapping: law / obligation → control id → evidence / system behavior — see [compliance-matrices/README.md](README.md). |
| **Complete (institution)** | All **in-scope** matrix rows for that institutions jurisdictions are **implemented or explicitly waived** with sign-off; URA pilots or production resources carry **non-placeholder** evidence where policy requires; RTGS matrix rows for the **chosen architecture** are `Complete` or **excluded with rationale** (see [DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md](../../03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md)). |
---
## RACI (summary)
| Activity | Responsible | Accountable | Consulted | Informed |
|----------|-------------|-------------|-----------|----------|
| Jurisdiction / law inventory | Compliance | Legal | Local counsel | Program, Eng |
| Compliance matrix draft | Compliance | Legal | Risk, Product | Eng |
| Policy profile version & registry | Product / Arch | Legal + Risk | Compliance | Eng |
| URA manifest & evidence packages | Ops | Compliance | Audit | Eng |
| RTGS / sidecar / OMNL integration | Eng | Program | Banking ops | Compliance |
| Rail / on-chain controls | Eng | Risk | Audit | Legal |
| Production gate sign-off | Program | Executive sponsor | Legal, Risk | All |
---
## Exit criteria (program slice 1)
1. [JURISDICTION_CATALOG.md](../jurisdictions/JURISDICTION_CATALOG.md) and [config/jurisdictions/catalog.v1.json](../../../config/jurisdictions/catalog.v1.json) list **in-scope** jurisdictions and activities.
2. [SLICE1_SCOPE_FREEZE.md](../jurisdictions/SLICE1_SCOPE_FREEZE.md) is agreed and references [DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](../../03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md) immediate priorities.
3. At least one **full** jurisdiction matrix exists (see [ID-INDONESIA/banking_v1.md](ID-INDONESIA/banking_v1.md)) plus [GENERIC-COMMON-LAW-STUB](GENERIC-COMMON-LAW-STUB/banking_v1.md) for process training and a **draft second jurisdiction** ([US-DELAWARE-CORP-STUB](US-DELAWARE-CORP-STUB/README.md)) for multi-matrix workflow rehearsal.
4. Policy profiles registered and validated in CI (`pnpm ura:validate-profiles`).
5. Traceability doc links controls to matrices — [DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md).
## Related
- [INSTITUTION_ONBOARDING_PLAYBOOK.md](INSTITUTION_ONBOARDING_PLAYBOOK.md) — step-by-step onboarding.
- [UNIVERSAL_RESOURCE_WIRING.md](../universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md) — URA ops.

View File

@@ -0,0 +1,67 @@
# Institution onboarding playbook — jurisdictions and compliance matrices
**Last updated:** 2026-04-25
**Purpose:** Repeatable steps to onboard an **institution** under one or more **jurisdictions**, producing signed compliance matrices, registered policy profiles, and URA/RTGS artifacts.
## Prerequisites
- [INSTITUTION_ONBOARDING_CHARTER.md](INSTITUTION_ONBOARDING_CHARTER.md) acknowledged (RACI).
- [JURISDICTION_CATALOG.md](../jurisdictions/JURISDICTION_CATALOG.md) and [`config/jurisdictions/catalog.v1.json`](../../config/jurisdictions/catalog.v1.json) updated for new jurisdictions.
- [SLICE1_SCOPE_FREEZE.md](../jurisdictions/SLICE1_SCOPE_FREEZE.md) or successor scope doc current.
---
## Steps
### 1. Legal and compliance intake
1. Institution name, regulator(s), licensed activities.
2. Build **law / regulation inventory** (counsel-owned citations).
3. Confirm **in-scope** vs **excluded** activities; align with RTGS matrix architecture choice.
### 2. Compliance matrix
1. Copy [_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md](_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md) to `docs/04-configuration/compliance-matrices/<JURISDICTION_CODE>/`.
2. Fill obligation rows; map **Control ids** to [DBIS_RAIL_CONTROL_MAPPING_V1.md](../../dbis-rail/DBIS_RAIL_CONTROL_MAPPING_V1.md) and add `<JUR>-*` ids as needed.
3. Link evidence expectations to ISO / 4.995 / institution package standards where applicable.
4. Update [DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md) when new obligation ↔ control links are stable.
### 3. Policy profiles
1. Add or extend entries in [`config/universal-resource-activation/policy-profiles.json`](../../config/universal-resource-activation/policy-profiles.json) (`jurisdictions[]`, `minimumGruGovernanceLevel`, `complianceMatrixPaths`).
2. Run `pnpm ura:validate-profiles`.
3. Update [UNIVERSAL_RESOURCE_POLICY_PROFILES.md](../universal-resource-activation/UNIVERSAL_RESOURCE_POLICY_PROFILES.md) if new profile semantics are introduced.
### 4. URA resources
1. Add or update rows in [`config/universal-resource-activation/manifest.json`](../../config/universal-resource-activation/manifest.json) with correct `policyProfileId`, `jurisdiction`, `ownerParticipantId`.
2. Follow [URA_PILOT_CLOSURE_RUNBOOK.md](../universal-resource-activation/URA_PILOT_CLOSURE_RUNBOOK.md) for evidence packages.
3. Run `pnpm ura:validate`.
### 5. RTGS / technical closure
1. Use [DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md](../../03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md) to assign workstreams.
2. Update [DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](../../03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md) when components reach **Complete**.
### 6. Automation (recommended)
| Action | Command / artifact |
|--------|-------------------|
| URA manifest + schemas | `pnpm ura:validate` |
| Policy registry + manifest refs | `pnpm ura:validate-profiles` |
| Merge manifest fragments (optional) | `pnpm ura:merge-manifest` · [`manifest-fragments/README.md`](../../../config/universal-resource-activation/manifest-fragments/README.md) |
| Production closure gate (no pilot/TBD) | `pnpm ura:validate-closure:strict` · or `URA_STRICT_CLOSURE=1` with `validate-config-files.sh` |
| Phoenix HTTP smoke (staging) | `pnpm ura:smoke -- --http` with `PHOENIX_BASE_URL` (manifest + policy-profiles + sidecar-probe) |
| On-chain id hashes | `pnpm ura:keccak` |
**Service-bound next steps:** manifest/ledger writers fed by OMNL/sidecar events — out of repo until those APIs are stable; use merge + manual `manifest.json` until then.
### 7. Exit
Institution **Complete** per charter when: matrix rows implemented or waived with sign-off, mandatory RTGS rows green for chosen architecture, URA evidence **matched** where policy requires.
## Related
- [compliance-matrices/README.md](README.md)
- [UNIVERSAL_RESOURCE_WIRING.md](../universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md)
- [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](../universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -0,0 +1,24 @@
# Per-jurisdiction compliance matrices
**Last updated:** 2026-04-25
**Purpose:** One **separate** matrix (or split by regime) per **onboarded jurisdiction**, mapping **local obligations****control IDs** (Rail + jurisdiction-specific) → **evidence / system behavior**.
## Index
| Jurisdiction code | Folder | Status |
|-------------------|--------|--------|
| _TEMPLATE | [_TEMPLATE/](_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md) | Use for new jurisdictions |
| GENERIC-COMMON-LAW-STUB | [GENERIC-COMMON-LAW-STUB/](GENERIC-COMMON-LAW-STUB/README.md) | Template only |
| ID (Indonesia) | [ID-INDONESIA/](ID-INDONESIA/README.md) | Pilot-ready |
| US-DELAWARE-CORP-STUB | [US-DELAWARE-CORP-STUB/](US-DELAWARE-CORP-STUB/README.md) | Draft (second jurisdiction exercise) |
## Governance
- [INSTITUTION_ONBOARDING_CHARTER.md](INSTITUTION_ONBOARDING_CHARTER.md) — RACI and definition of **Complete**.
- [JURISDICTION_CATALOG.md](../jurisdictions/JURISDICTION_CATALOG.md) — catalog index.
- [INSTITUTION_ONBOARDING_PLAYBOOK.md](INSTITUTION_ONBOARDING_PLAYBOOK.md) — onboarding steps (Phase 6).
## Related
- [DBIS_RAIL_CONTROL_MAPPING_V1.md](../../dbis-rail/DBIS_RAIL_CONTROL_MAPPING_V1.md)
- [DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md)

View File

@@ -0,0 +1,9 @@
# US-DELAWARE-CORP-STUB — draft (second jurisdiction template)
**Status:** **draft** — placeholder for a second jurisdiction onboarding exercise. **Not** production-ready; no counsel review recorded.
Replace this stub with a real US state / federal matrix when an institution requires it, or delete if out of scope.
| File | Regime / topic |
|------|----------------|
| [banking_v1.md](banking_v1.md) | Draft starter rows (fictional placeholders) |

View File

@@ -0,0 +1,25 @@
# Compliance matrix — US-DELAWARE-CORP-STUB — banking_v1 (DRAFT)
**Last updated:** 2026-04-25
**Status:** **draft** — second-jurisdiction process training only. **Do not** use for compliance claims.
## 1. Law / regulation inventory (placeholders — replace with counsel research)
| Ref id | Short title | Scope | Notes |
|--------|-------------|-------|-------|
| US-D-STUB-001 | Illustrative: corporate treasury governance | corporate | Fictional row for template practice. |
| US-D-STUB-002 | Illustrative: AML program expectations | AML | Fictional. |
## 2. Requirement mapping (starter)
| Matrix row id | Obligation summary | URA family | Control ids | Evidence |
|---------------|-------------------|------------|-------------|----------|
| US-STUB-001 | Illustrative: treasury policy for server funds | `SERVER_FUNDS` | C8, C17 | OMNL refs + policy attestation |
| US-STUB-002 | Illustrative: custody evidence for SKR | `SKR_SAFEKEEPING` | C9 | Custodian hash / WORM id |
## 3. Next steps
1. Rename jurisdiction folder to the agreed code (e.g. state + program).
2. Replace inventory with **real** citations.
3. Register profiles in [`policy-profiles.json`](../../../config/universal-resource-activation/policy-profiles.json) if new `policyProfileId`s are needed.
4. Add row to [`config/jurisdictions/catalog.v1.json`](../../../config/jurisdictions/catalog.v1.json) with `status: pilot_ready` when reviewed.

View File

@@ -0,0 +1,45 @@
# Compliance matrix — `<JURISDICTION_CODE>` — `<REGIME_OR_TOPIC>_v1`
**Last updated:** YYYY-MM-DD
**Jurisdiction id:** `<ISO or program code, e.g. ID, US-NY>`
**Owning counsel / compliance:** `<Name or role — not legal advice in this file>`
**Effective from / to:** `<dates or “until superseded”>`
**Related `policyProfileId`(s):** `<list>`
**Related URA families:** `SKR_SAFEKEEPING` | `SERVER_FUNDS` | `INFRA_CAPACITY` | …
---
## 1. Law / regulation inventory
| Ref id | Short title | Scope (banking, securities, AML, DP, FX, digital assets) | Notes |
|--------|-------------|---------------------------------------------------------------|-------|
| LAW-001 | `<Statute or reg>` | `<scope>` | `<counsel summary>` |
---
## 2. Requirement and control mapping
| Matrix row id | Obligation summary (non-legal) | Participant classes | URA family | Enforcement (on-chain / off-chain / hybrid) | Control ids | Evidence expectation |
|---------------|--------------------------------|---------------------|------------|---------------------------------------------|-------------|----------------------|
| `<JUR>-001` | `<e.g. KYC for treasury operators>` | `<institutional>` | `SERVER_FUNDS` | off-chain | `C7` [Rail mapping](../../dbis-rail/DBIS_RAIL_CONTROL_MAPPING_V1.md), `<JUR>-AML-001` | `<ISO package / audit artifact>` |
**Control id conventions**
- **C1C18:** [DBIS_RAIL_CONTROL_MAPPING_V1.md](../../dbis-rail/DBIS_RAIL_CONTROL_MAPPING_V1.md) where applicable.
- **`<JUR>-*`** jurisdiction-specific controls not covered by Rail mapping.
---
## 3. Residual risk / exceptions
| Topic | Decision | Owner |
|-------|----------|-------|
| Manual vs automated control | `<>` | `<>` |
---
## 4. Document control
| Version | Date | Author | Change |
|---------|------|--------|--------|
| 0.1 | YYYY-MM-DD | `<>` | Draft |

View File

@@ -0,0 +1,22 @@
# Jurisdiction catalog (human index)
**Last updated:** 2026-04-25
**Machine-readable source:** [`config/jurisdictions/catalog.v1.json`](../../config/jurisdictions/catalog.v1.json)
| ID | Label | Compliance matrix | Status | Notes |
|----|-------|-------------------|--------|--------|
| ID | Indonesia | [ID-INDONESIA/banking_v1.md](../compliance-matrices/ID-INDONESIA/banking_v1.md) | pilot_ready | Align with BNI / OMNL / 4.995 evidence paths. |
| GENERIC-COMMON-LAW-STUB | Template stub | [GENERIC-COMMON-LAW-STUB/README.md](../compliance-matrices/GENERIC-COMMON-LAW-STUB/README.md) | template_only | Train process only; not for production. |
| US-DELAWARE-CORP-STUB | US draft stub | [US-DELAWARE-CORP-STUB/README.md](../compliance-matrices/US-DELAWARE-CORP-STUB/README.md) | draft | Second-jurisdiction placeholder; replace or remove. |
## Adding a jurisdiction
1. Add an object to `catalog.v1.json` with `id`, `label`, paths, `status`.
2. Create `docs/04-configuration/compliance-matrices/<id>/` using [_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md](../compliance-matrices/_TEMPLATE/COMPLIANCE_MATRIX_TEMPLATE.md).
3. Register or extend [policy-profiles.json](../../config/universal-resource-activation/policy-profiles.json) entries with `jurisdictions[]`.
4. Update [DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md) when controls are mapped.
## Related
- [INSTITUTION_ONBOARDING_CHARTER.md](../compliance-matrices/INSTITUTION_ONBOARDING_CHARTER.md)
- [SLICE1_SCOPE_FREEZE.md](SLICE1_SCOPE_FREEZE.md)

View File

@@ -0,0 +1,36 @@
# Slice 1 scope freeze (RTGS + URA alignment)
**Last updated:** 2026-04-25
**Purpose:** Operational **scope freeze** for production slice 1, aligned with [DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](../../03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md) **Immediate execution priority** and URA pilots.
## Frozen priorities (from RTGS matrix)
1. **Freeze the canonical banking rail** on the proven OMNL / Fineract tenant and authenticated posting path.
2. **Freeze participant / treasury / GL model** (and dependent depository, custody, FX, liquidity layers as in-scope for slice 1).
3. **Complete the canonical settlement path** from HYBX sidecars into Chain 138 with durable evidence.
## In-scope for slice 1 (default)
- OMNL / Fineract operator rail and officeGL mapping (as documented in matrix rows).
- HYBX first-slice sidecars: **`mifos-fineract-sidecar`**, **`server-funds-sidecar`**, **`off-ledger-2-on-ledger-sidecar`** — business flows and evidence, not only health.
- ISO 20022 / institutional evidence packaging toward **submission-grade** where matrix requires.
- Indonesia domestic path **when** institution is Indonesia-facing — see [ID-INDONESIA compliance matrix](../compliance-matrices/ID-INDONESIA/banking_v1.md).
- URA [pilot plan](../universal-resource-activation/UNIVERSAL_RESOURCE_PILOT_PLAN.md) closure per [URA_PILOT_CLOSURE_RUNBOOK.md](../universal-resource-activation/URA_PILOT_CLOSURE_RUNBOOK.md).
## Explicitly out of scope for slice 1 (unless program re-opens)
- Fabric / Indy / Aries **production** until matrix rows move from Planned/Reserved to Complete with validation.
- Mojaloop, card networks, flash-loan XAU, etc., unless a **written scope addendum** promotes them.
- **Template-only** jurisdiction [GENERIC-COMMON-LAW-STUB](../compliance-matrices/GENERIC-COMMON-LAW-STUB/banking_v1.md) — never production.
## Change control
Any change to this freeze requires: Program owner + Legal/Compliance acknowledgment and update to this files **Last updated** and a short **revision note** block (append below).
---
## Revision history
| Date | Change |
|------|--------|
| 2026-04-25 | Initial slice 1 freeze document created from master plan. |

View File

@@ -15,11 +15,17 @@
| [UNIVERSAL_RESOURCE_INFRA_CAPACITY_LANE.md](UNIVERSAL_RESOURCE_INFRA_CAPACITY_LANE.md) | Infrastructure capacity lane: inventory, bundles, broker, metering |
| [UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md](UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md) | Shared evidence and reconciliation package |
| [UNIVERSAL_RESOURCE_PILOT_PLAN.md](UNIVERSAL_RESOURCE_PILOT_PLAN.md) | First three pilots (SKR, server funds, infra) |
| [URA_PILOT_CLOSURE_RUNBOOK.md](URA_PILOT_CLOSURE_RUNBOOK.md) | Replace manifest placeholders; close pilots and evidence |
| [policy-profiles.json (registry)](../../config/universal-resource-activation/policy-profiles.json) | Machine-readable profiles + GRU governance level |
| [POLICY_PROFILES_REGISTRY.md](../../config/universal-resource-activation/POLICY_PROFILES_REGISTRY.md) | Doc control / sign-off table per profile version |
| [MANIFEST_AUTOMATION_DESIGN.md](../../config/universal-resource-activation/MANIFEST_AUTOMATION_DESIGN.md) | Future manifest merge/CI design (not implemented) |
| [Compliance matrices / onboarding](../compliance-matrices/README.md) | Per-jurisdiction matrices, charter, playbook |
| [Jurisdiction catalog](../jurisdictions/JURISDICTION_CATALOG.md) | Catalog index + `config/jurisdictions/catalog.v1.json` |
| [JSON Schema v1](../../../config/universal-resource-activation.resource.v1.schema.json) | Machine-readable resource body (`UniversalResource` subset) |
| [URAWiring / ops](UNIVERSAL_RESOURCE_WIRING.md) | **Manifest, CI validation, Phoenix `GET` route, env overrides** |
| [manifest.json (live store)](../../../config/universal-resource-activation/manifest.json) | In-repo `resources[]` and `evidencePackages[]` |
**Validate:** `node scripts/validate/validate-universal-resource-activation.mjs` (from repo root) · **smoke (schema ± HTTP):** `bash scripts/verify/smoke-universal-resource-activation.sh` — [wiring §2.1](UNIVERSAL_RESOURCE_WIRING.md#21-testing-checklist)
**Validate:** `pnpm ura:validate` · `pnpm ura:validate-profiles` · **merge fragments:** `pnpm ura:merge-manifest` · **ledger mapping:** `pnpm ura:validate-ledger-mapping` · **writers:** `pnpm ura:writer:ledger` / `pnpm ura:writer:settlement` · **profile hash (on-chain anchor):** `pnpm ura:profile-hash` · **closure gate:** `pnpm ura:validate-closure` / `pnpm ura:validate-closure:strict` · **smoke:** `pnpm ura:smoke` (add `--http` for Phoenix: manifest + policy-profiles + sidecar-probe) · **on-chain id hashes:** `pnpm ura:keccak` — [wiring §2.1](UNIVERSAL_RESOURCE_WIRING.md#21-testing-checklist) · **full automation tracker:** [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)
## Upstream anchors

View File

@@ -0,0 +1,27 @@
# SKR / custody — automation notes for `evidenceRefs`
**Last updated:** 2026-04-25
**Purpose:** Guide for **Pilot 1** automation: populating [`manifest.json`](../../../config/universal-resource-activation/manifest.json) `evidenceRefs` and evidence package `custodyOrSourceEvidence` from custodian or internal systems.
## 1. Typical sources
| Source | Pattern |
|--------|---------|
| **Custodian API** | Poll or webhook for statement id / secure URL; store hash in manifest. |
| **Signed PDF / ISO package** | Landing zone (S3, SFTP); writer computes SHA-256; `evidenceRefs` = `sha256:…` or object URL + hash. |
| **Internal attestation** | HSM-signed payload; reference id in manifest. |
## 2. Jurisdiction
Obligations live in the per-jurisdiction matrix (e.g. [ID-INDONESIA/banking_v1.md](../compliance-matrices/ID-INDONESIA/banking_v1.md)). Automation must not change **meaning** of evidence without counsel review.
## 3. Implementation sketch
1. Custody ETL outputs JSON `{ "statementId", "hash", "effectiveDate" }`.
2. Extend [`build-ledger-fragment.mjs`](../../../scripts/ura/manifest-writer/build-ledger-fragment.mjs) pattern with a **custody fragment** script (future) or reuse merge fragments manually.
3. Run `pnpm ura:validate` and `pnpm ura:validate-closure:strict` before production CI enables strict mode.
## Related
- [`URA_PILOT_CLOSURE_RUNBOOK.md`](URA_PILOT_CLOSURE_RUNBOOK.md) §2
- [`URA_MANIFEST_WRITER_OPS.md`](../../03-deployment/URA_MANIFEST_WRITER_OPS.md)

View File

@@ -1,6 +1,6 @@
# Shared Evidence and Reconciliation Package
**Last updated:** 2026-04-24
**Last updated:** 2026-04-25
**Purpose:** A single **reproducible evidence package** for every **resource activation** and cross-lane action (SKR, server funds, infra, settlement). Aligns with ISO-20022 and institutional audit patterns referenced in [DBIS Rail technical spec](../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md) and the custody operating model in [DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md](../../03-deployment/DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md).
## Design principles
@@ -30,6 +30,8 @@
| `reconciliationStatus` | `open`, `matched`, `exception` |
| `explanation` | Human-readable for auditors |
Use **`reconciliationStatus = open`** when mandatory joins (e.g. a real `accountingRef` or `settlementOrChainRef` where policy requires them) are not yet present or verified; set **`matched`** only after those joins succeed in the same reconciliation window. Bootstrap packages with TBD text placeholders should stay **`open`**.
## Minimum object set by lane
| Lane | Must include |

View File

@@ -1,6 +1,6 @@
# Universal Resource Ontology
**Last updated:** 2026-04-24
**Last updated:** 2026-04-25
**Purpose:** Define the canonical **resource** model used across financial and infrastructure lanes. This is the schema contract for registries, APIs, and (when applicable) on-chain mirrors.
## Design principles
@@ -19,6 +19,8 @@
| `createdAt` | RFC3339 / epoch | Audit. |
| `updatedAt` | RFC3339 / epoch | Audit. |
**In-repo manifest (human-readable URNs):** The [URA `manifest.json`](../../config/universal-resource-activation/manifest.json) may use stable string IDs such as `ura:pilot-1:…` for reviewability. For optional EVM anchoring, derive **`keccak256(utf8(resourceId))`** (same as `node scripts/ura/keccak-resource-ids.mjs`); the manifest string remains the canonical off-chain id unless you later standardize on bytes32 at rest.
## Resource families
`family` discriminates top-level behavior and which lane adapters apply.

View File

@@ -1,10 +1,12 @@
# First Three Pilots — Universal Resource Activation
**Last updated:** 2026-04-24
**Last updated:** 2026-04-25
**Purpose:** Operable, low-risk **pilots** that validate the ontology, policy profiles, each lane, and the shared [evidence package](UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md) before broad rollout.
**Governance default:** `tokenizationMode = NONE` and conservative `deployabilityState` for all three pilots.
**In-repo `manifest.json` (bootstrap):** The shared [`config/universal-resource-activation/manifest.json`](../../config/universal-resource-activation/manifest.json) uses **pilot-scoped** `resourceId`s and may keep the pilot evidence package at **`reconciliationStatus: open`** while `accountingRef` / `settlementOrChainRef` (or other mandatory joins) are still TBD. The “Done when” columns below are **end states** for each pilot, not a live mirror of the JSON on every row. Update the manifest to **`matched`** when the corresponding pilots reconciliation is closed (see [UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md](UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md)).
---
## Pilot 1 — SKR- or statement-backed resource record (custody or strategic with evidence)

View File

@@ -1,6 +1,6 @@
# Universal Resource Policy Profiles
**Last updated:** 2026-04-24
**Last updated:** 2026-04-25
**Purpose:** Define **modular policy profiles** that bind legal, regulatory, compliance, accounting, valuation, and transferability rules to resources without hardcoding jurisdiction logic in each adapter.
## Why profiles
@@ -105,6 +105,16 @@ Map to on-chain or off-chain enforcement:
3. `effectiveFrom` in production; keep prior versions for historical reconciliation.
4. Emit `PolicyProfileUpdated` (off-chain) or on-chain event if a chain registry is used.
## Machine-readable registry (CI)
Production-facing profiles SHOULD be listed in [`config/universal-resource-activation/policy-profiles.json`](../../config/universal-resource-activation/policy-profiles.json) (JSON Schema: [`universal-resource-activation.policy-profile-registry.v1.schema.json`](../../config/universal-resource-activation.policy-profile-registry.v1.schema.json)). Each entry includes **`minimumGruGovernanceLevel`** (05) per [GRU_M00_DIAMOND_FACET_MAP.md](../GRU_M00_DIAMOND_FACET_MAP.md) §4.
**Doc control:** [`POLICY_PROFILES_REGISTRY.md`](../../config/universal-resource-activation/POLICY_PROFILES_REGISTRY.md) — sign-off table per profile version.
**Validate:** `pnpm ura:validate-profiles` — also invoked from [`scripts/validation/validate-config-files.sh`](../../../scripts/validation/validate-config-files.sh).
**Per-jurisdiction matrices:** [`docs/04-configuration/compliance-matrices/`](../compliance-matrices/README.md).
## Related
- [UNIVERSAL_RESOURCE_ONTOLOGY.md](UNIVERSAL_RESOURCE_ONTOLOGY.md)

View File

@@ -1,6 +1,6 @@
# Universal Resource Activation — Wiring and Operations
**Last updated:** 2026-04-24
**Last updated:** 2026-04-25
This document describes how the **in-repo** universal resource system is wired: config store, JSON schemas, validation in CI, and the Phoenix Deploy API.
@@ -30,34 +30,45 @@ node scripts/validate/validate-universal-resource-activation.mjs
| 1. JSON Schema (manifest, each resource, each evidence row) | `node scripts/validate/validate-universal-resource-activation.mjs` | Invalid or incomplete JSON vs schemas |
| 2. Full config gate (includes step 1) | `bash scripts/validation/validate-config-files.sh` | Any required project config check fails |
| 3. CI-style aggregate | `bash scripts/verify/run-all-validation.sh --skip-genesis` | Any step in the wrapper fails |
| 4. URA smoke (schema + optional HTTP) | `bash scripts/verify/smoke-universal-resource-activation.sh` | Step 1 fails. With `--http` (or `PHOENIX_BASE_URL=…`), also fails if Phoenix does not return HTTP 200 JSON with `.schemaVersion` at `/api/v1/universal-resource-activation/manifest` |
| 5. OpenAPI / Swagger | Open `http://<host>:<port>/api-docs` on `phoenix-deploy-api` and confirm `GET /api/v1/universal-resource-activation/manifest` is listed (see [`phoenix-deploy-api/openapi.yaml`](../../../phoenix-deploy-api/openapi.yaml)) | N/A (manual) |
| 4. URA smoke (schema + optional HTTP) | `bash scripts/verify/smoke-universal-resource-activation.sh` | Step 1 fails. With `--http` (or `PHOENIX_BASE_URL=…`), checks `GET …/manifest` (200 + `.schemaVersion`), `GET …/policy-profiles` (200 + `.profiles` array), and `GET …/server-funds-sidecar-probe` (**200** = sidecar or probe ok JSON; **503** + `configured: false` = URL unset, OK for dev; **502** = URL set but sidecar unreachable) |
| 4b. On-chain / GRU hash (optional) | `node scripts/ura/keccak-resource-ids.mjs` | Prints `keccak256(utf8(resourceId))` per row (requires root `ethers`); does not block CI |
| 4c. Server-funds sidecar probe (optional) | `curl` `GET /api/v1/universal-resource-activation/server-funds-sidecar-probe` on Phoenix | `503` + `configured:false` until `SERVER_FUNDS_SIDECAR_URL` is set; `200` when a health path returns 2xx |
| 5. OpenAPI / Swagger | Open `http://<host>:<port>/api-docs` on `phoenix-deploy-api` and confirm URA paths (see [`phoenix-deploy-api/openapi.yaml`](../../../phoenix-deploy-api/openapi.yaml)) | N/A (manual) |
**Operator note:** `smoke-universal-resource-activation.sh` without flags only runs steps that need Node (no live Phoenix). Use `PHOENIX_BASE_URL=http://127.0.0.1:4001 bash scripts/verify/smoke-universal-resource-activation.sh --http` when the API is up on that host.
**Operator note:** `smoke-universal-resource-activation.sh` without flags only runs steps that need Node (no live Phoenix). With Phoenix up: `PHOENIX_BASE_URL=http://127.0.0.1:4001 bash scripts/verify/smoke-universal-resource-activation.sh --http` (default base `http://127.0.0.1:4001` if unset with `--http`).
## 3. Phoenix Deploy API (read-only)
The API exposes the manifest as **JSON** without a partner API key (same pattern as the public-sector program manifest).
The API exposes the manifest and policy profile registry as **JSON** without a partner API key (same pattern as the public-sector program manifest).
| | |
|--|--|
| **Endpoint** | `GET /api/v1/universal-resource-activation/manifest` |
| **Override path** | Set `UNIVERSAL_RESOURCE_MANIFEST_PATH` to a full file path. |
| **Default resolution** | `PHOENIX_REPO_ROOT` (or `PROXMOX_REPO_PATH`) + `config/universal-resource-activation/manifest.json`, or `../config/...` when running with `phoenix-deploy-api` CWD. |
| **Manifest** | `GET /api/v1/universal-resource-activation/manifest` |
| **Policy profiles** | `GET /api/v1/universal-resource-activation/policy-profiles` |
| **Manifest override** | `UNIVERSAL_RESOURCE_MANIFEST_PATH` (full file path). |
| **Policy registry override** | `UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH` (full file path). |
| **Default resolution** | `PHOENIX_REPO_ROOT` (or `PROXMOX_REPO_PATH`) + `config/universal-resource-activation/{manifest.json,policy-profiles.json}`, or `../config/...` when running with `phoenix-deploy-api` CWD. |
**Implementation:** [phoenix-deploy-api/server.js](../../../phoenix-deploy-api/server.js) — `resolveUniversalResourceManifestPath`, route registered before `partnerKeyMiddleware`.
**Implementation:** [phoenix-deploy-api/server.js](../../../phoenix-deploy-api/server.js) — `resolveUniversalResourceManifestPath`, `resolveUniversalResourcePolicyProfilesPath`, routes registered before `partnerKeyMiddleware`.
## 4. Gitea / Phoenix deploy
When Gitea deploy syncs the `d-bis/proxmox` archive, the `config/` tree (including `config/universal-resource-activation/`) is part of the synced subtree. The Phoenix host can serve the manifest as soon as the file is present under `PHOENIX_REPO_ROOT`.
## 5. Future wiring (out of this pass)
## 5. Integration tools (in-repo; operator or next phase)
- **On-chain / GRU M00:** When `UniversalAssetRegistry` and M00 are the SoR, mirror or hash `resourceId` into on-chain registries; keep the manifest as operator/air-gapped copy until a dedicated DB is introduced.
- **OMNL / `server-funds-sidecar`:** Add API calls to register draws/holds; store returned `accountingRef` in new evidence package rows in `manifest.json` or a database — follow [UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md](UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md).
- **DBIS Rail:** Link `settlementOrChainRef` in evidence packages to `MintAuth` / settlement router events per [DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md).
- **Manifest fragments + merge:** Drop partial JSON under `config/universal-resource-activation/manifest-fragments/` and run `pnpm ura:merge-manifest` (validate-only) or `node scripts/ura/merge-manifest-fragments.mjs --out <file>`. See [manifest-fragments/README.md](../../../config/universal-resource-activation/manifest-fragments/README.md) and [MANIFEST_AUTOMATION_DESIGN.md](../../../config/universal-resource-activation/MANIFEST_AUTOMATION_DESIGN.md). **Task index:** [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md).
- **Ledger / Rail fragments:** `pnpm ura:writer:ledger`, `pnpm ura:writer:settlement`, `pnpm ura:validate-ledger-mapping` — [manifest-writer/README.md](../../../scripts/ura/manifest-writer/README.md); settlement sources: [DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md](../../dbis-rail/DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md); ops: [URA_MANIFEST_WRITER_OPS.md](../../03-deployment/URA_MANIFEST_WRITER_OPS.md).
- **On-chain policy anchor (standalone):** `PolicyProfileRegistry` in `smom-dbis-138` + `pnpm ura:profile-hash` — [GRU_REGISTRY_WIRING_CHECKLIST.md](../../runbooks/GRU_REGISTRY_WIRING_CHECKLIST.md) §6.
- **Production closure gate:** `pnpm ura:validate-closure` (warnings) or `pnpm ura:validate-closure:strict` (exit 1 on pilot ids, pending evidence refs, `TBD` in evidence fields, or `reconciliationStatus: open`). Optional CI: `URA_STRICT_CLOSURE=1` with `validate-config-files.sh`.
- **On-chain / GRU M00:** Canonical manifest stays the off-chain store. To **derive** EVM keccak for optional registry anchoring: `node scripts/ura/keccak-resource-ids.mjs` (uses `ethers` v6; prints one hash per `resourceId`). On-chain contract wiring remains a separate deployment task.
- **OMNL / `server-funds-sidecar`:** Phoenix exposes **`GET /api/v1/universal-resource-activation/server-funds-sidecar-probe`** (no API key). Set `SERVER_FUNDS_SIDECAR_URL` to the sidecar base URL; optional `SERVER_FUNDS_SIDECAR_HEALTH_PATH` for a first path. Returns **503** with a configuration hint if unset. Draw/hold APIs and writing `accountingRef` into the manifest (or a DB) remain follow-on work per [UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md](UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md).
- **DBIS Rail / MintAuth:** Evidence packages support **`settlementOrChainRef`** in JSON Schema. Populate the manifest with live settlement or event refs when the pilot posts to the rail; see [UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md](UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md) and [DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md). Automated mirroring is out of scope until services expose stable query endpoints.
## Related
- [README.md](README.md) — document map
- [README.md](README.md) — document map
- [technical-specs/README.md](technical-specs/README.md) — normative TS-* specs for OMNL/sidecar, settlement indexer, SKR ETL, GRU program, compliance sign-off
- [URA_PILOT_CLOSURE_RUNBOOK.md](URA_PILOT_CLOSURE_RUNBOOK.md) — close pilots / replace placeholders
- [../compliance-matrices/README.md](../compliance-matrices/README.md) — jurisdiction matrices and onboarding charter/playbook
- [../README.md](../README.md) (04-configuration) — main index

View File

@@ -0,0 +1,54 @@
# URA manifest automation — implementation tracker
**Last updated:** 2026-04-25
**Purpose:** Single checklist for **OMNL/ledger → manifest**, **chain/Rail → manifest**, **GRU/on-chain registry**, and **ops gates**. Repo artifacts are linked; rows that need live services name the owning team.
**Legend:** **Done (repo)** = implemented or specified in this monorepo. **Operator** = execution on your LAN/RPC/Fineract deployment.
**Normative technical specs (remaining implementation):** [technical-specs/README.md](technical-specs/README.md) — RFC 2119 requirements, interfaces, acceptance tests for pending workstreams.
| ID | Task | Status | Artifact / next step |
|----|------|--------|----------------------|
| ura-auto-01 | OMNL/Fineract APIs → `accountingRef` | **Done (repo)** | [`URA_MANIFEST_WRITER_OPS.md`](../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §2; mapping schema |
| ura-auto-02 | Server-funds sidecar ↔ ledger | **Operator** | Todo `ura-auto-02`; RTGS tracker; Phoenix probe only today |
| ura-auto-03 | Mapping table (idempotency) | **Done (repo)** | [`omnl-ledger-mapping.v1.schema.json`](../../../config/universal-resource-activation/integration/omnl-ledger-mapping.v1.schema.json) |
| ura-auto-04 | Manifest writer job | **Done (repo)** | [`build-ledger-fragment.mjs`](../../../scripts/ura/manifest-writer/build-ledger-fragment.mjs), [`merge-manifest-fragments.mjs`](../../../scripts/ura/merge-manifest-fragments.mjs) |
| ura-auto-05 | Publish path (git/sync/API) | **Operator** | [`URA_MANIFEST_WRITER_OPS.md`](../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §4 |
| ura-auto-06 | Secrets & IAM | **Operator** | Same doc §3 |
| ura-auto-07 | Reconciliation / drift | **Done (repo)** | Spec in ops doc §5; implement alerts in your APM |
| ura-auto-08 | E2E staging | **Operator** | Todo `ura-auto-08`; run writer + `pnpm ura:validate` after real journal export |
| ura-auto-opt-a | Real-time vs batch | **Done (repo)** | Ops doc §6 optional |
| ura-auto-opt-b | Multi-pool / DLQ / audit log | **Done (repo)** | Ops doc §6 optional |
| chain-01 | Rail settlement event sources | **Done (repo)** | [`DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md`](../../dbis-rail/DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md) |
| chain-02 | Indexer → `settlementOrChainRef` | **Partial (repo)** | Fragment CLI: [`build-settlement-fragment.mjs`](../../../scripts/ura/manifest-writer/build-settlement-fragment.mjs); **Operator:** Todo `chain-02` (live listener) |
| chain-03 | SKR custody automation | **Partial (repo)** | [`SKR_CUSTODY_AUTOMATION_NOTES.md`](SKR_CUSTODY_AUTOMATION_NOTES.md); **Operator:** custodian ETL |
| chain-opt-a | Anchor manifest hash on-chain | **Operator** | Optional pattern in settlement doc |
| chain-opt-b | `keccak(resourceId)` in registry | **Operator** | After GRU facet; use [`keccak-resource-ids.mjs`](../../../scripts/ura/keccak-resource-ids.mjs) |
| gru-01 | Lock GRC → M00 strategy | **Operator** | Todo `gru-01`; [`GRU_REGISTRY_WIRING_CHECKLIST.md`](../../runbooks/GRU_REGISTRY_WIRING_CHECKLIST.md) §1 |
| gru-02 | GRUStorage + bitmask | **Operator** | Todo `gru-02`; checklist §2 + facet map |
| gru-03 | Minimum ship facets | **Operator** | Todo `gru-03`; checklist §3 (Solidity) |
| gru-04 | Asset registry / Token factory | **Operator** | Todo `gru-04`; checklist §4 |
| gru-05 | Deploy & verify M00 | **Operator** | Todo `gru-05`; [`GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md`](../../runbooks/GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md) |
| gru-06 | Multisig / pause drills | **Operator** | Todo `gru-06`; checklist §5 |
| gru-07 | On-chain policy profile registry | **Done (repo)** | `smom-dbis-138/contracts/universal-resource/PolicyProfileRegistry.sol` + [`policy-profiles-content-hash.mjs`](../../../scripts/ura/policy-profiles-content-hash.mjs) |
| gru-08 | Doc handoff (Phoenix/URA) | **Done (repo)** | This file + [`UNIVERSAL_RESOURCE_WIRING.md`](UNIVERSAL_RESOURCE_WIRING.md) §5 |
| gru-opt-a | Oracle / cross-chain mirror | **Operator** | Checklist §7 |
| gru-opt-b | External audit / formal verification | **Cancelled** | Vendor scope; not automatable in-repo |
| xc-01 | `URA_STRICT_CLOSURE` in CI | **Done (repo)** | [`.gitea/workflows/validate-on-pr.yml`](../../../.gitea/workflows/validate-on-pr.yml) (documented env); [`validate-config-files.sh`](../../../scripts/validation/validate-config-files.sh) |
| xc-02 | Legal sign-off on automation | **Operator** | Todo `xc-02` (counsel); template in [`URA_MANIFEST_WRITER_OPS.md`](../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §7 |
| xc-03 | DR / rollback | **Done (repo)** | Ops doc §8 |
## Quick commands
```bash
pnpm ura:validate-ledger-mapping
pnpm ura:writer:ledger -- --mapping config/universal-resource-activation/integration/omnl-ledger-mapping.v1.example.json --ledger config/universal-resource-activation/integration/examples/ledger-snapshot.example.json
pnpm ura:writer:settlement -- --evidence-package-id ura:pilot:evidence-register-bootstrap --message-id 0x1 --tx-hash 0x2 --chain-id 138
pnpm ura:profile-hash institutional_custody_skr_v1
cd smom-dbis-138 && FORGE_SCOPE=universal-resource bash scripts/forge/scope.sh test --match-contract PolicyProfileRegistryTest
```
## Related
- [`MANIFEST_AUTOMATION_DESIGN.md`](../../../config/universal-resource-activation/MANIFEST_AUTOMATION_DESIGN.md)
- [`URA_PILOT_CLOSURE_RUNBOOK.md`](URA_PILOT_CLOSURE_RUNBOOK.md)

View File

@@ -0,0 +1,62 @@
# URA pilot closure runbook — replace placeholders with working components
**Last updated:** 2026-04-25
**Purpose:** Operator checklist to move [`config/universal-resource-activation/manifest.json`](../../config/universal-resource-activation/manifest.json) from **bootstrap** to **pilot-closed** state, aligned with [UNIVERSAL_RESOURCE_PILOT_PLAN.md](UNIVERSAL_RESOURCE_PILOT_PLAN.md) and jurisdiction matrices (e.g. [ID-INDONESIA/banking_v1.md](../compliance-matrices/ID-INDONESIA/banking_v1.md)).
**Before production:** run `pnpm ura:validate` and `pnpm ura:validate-profiles`; legal/compliance must sign off obligation coverage in the compliance matrix.
---
## 1. Participant and jurisdiction (all resources)
| Step | Action | Manifest fields |
|------|--------|-----------------|
| 1.1 | Register institution in your participant registry; assign stable id. | `ownerParticipantId` — replace `ura:participant:pilot-*-assign` with canonical id. |
| 1.2 | Confirm governing jurisdiction(s) with counsel. | `jurisdiction` — use catalog code (e.g. `ID`) or agreed tag; not `TBD`. |
| 1.3 | Align profile with registry. | `policyProfileId` must exist in [policy-profiles.json](../../config/universal-resource-activation/policy-profiles.json). |
---
## 2. Pilot 1 — SKR / custody
| Step | Action | Manifest / evidence |
|------|--------|---------------------|
| 2.1 | Attach custodian / strategic evidence. | `evidenceRefs[]` — hashes, object ids, or signed manifest refs. |
| 2.2 | Advance lifecycle per policy. | `lifecycleState` e.g. `pending_validation``active` when appropriate. |
| 2.3 | Evidence package | Add or update package with `custodyOrSourceEvidence` pointing to SKR row; keep `reconciliationStatus` **open** until validator sign-off, then **matched** if all joins satisfied. |
---
## 3. Pilot 2 — Server funds
| Step | Action | Manifest / evidence |
|------|--------|---------------------|
| 3.1 | Ensure `SERVER_FUNDS_SIDECAR_URL` and live draw/hold/release path. | Phoenix probe 200; see [UNIVERSAL_RESOURCE_WIRING.md](UNIVERSAL_RESOURCE_WIRING.md). |
| 3.2 | Capture ledger reference. | `accountingRef` — real OMNL / Fineract / batch id (not narrative TBD). |
| 3.3 | Capture rail / chain ref if used. | `settlementOrChainRef` — MintAuth `messageId`, tx hash, or rail id per [DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md). |
| 3.4 | Update notional if policy tracks pool balance. | `quantity` / `unitOfMeasure` on SERVER_FUNDS resource. |
---
## 4. Pilot 3 — Infra capacity
| Step | Action | Manifest / evidence |
|------|--------|---------------------|
| 4.1 | Verify host and bundle against inventory. | `infraHostId`, `infraBundleId`; `evidenceRefs` may link to storage / VMID reports. |
| 4.2 | After deploy, record deployment. | Evidence package `deploymentRef` — VMID, FQDN, health URL. |
| 4.3 | Meter and reconcile. | Additional evidence package or same package with metering refs; `reconciliationStatus` **matched** when FinOps agrees. |
---
## 5. Bootstrap evidence package closure
| Step | Action |
|------|--------|
| 5.1 | When pilots 13 mandatory joins are satisfied, set `reconciliationStatus` to **`matched`**. |
| 5.2 | Set `manifest.json` top-level `updatedAt` to RFC3339 UTC. |
| 5.3 | Re-run `pnpm ura:validate` and deploy manifest path on Phoenix (`PHOENIX_REPO_ROOT` / `UNIVERSAL_RESOURCE_MANIFEST_PATH`). |
## Related
- [DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md](../../03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md)
- [INSTITUTION_ONBOARDING_PLAYBOOK.md](../compliance-matrices/INSTITUTION_ONBOARDING_PLAYBOOK.md)

View File

@@ -0,0 +1,23 @@
# URA / RTGS / GRU — technical specifications (remaining implementation)
**Last updated:** 2026-04-25
**Purpose:** Normative **implementation** specifications for work that is still **operator- or engineering-pending** after repo scaffolding (writers, mapping schema, `PolicyProfileRegistry`, docs). These specs **do not replace** authoritative architecture documents; they bind them to testable interfaces and acceptance criteria.
## Document control
| ID | Title | Covers (tracker / todo ids) | Normative references |
|----|--------|----------------------------|----------------------|
| [TS-OMNL-SIDECAR-MANIFEST-SYNC-V1.md](TS-OMNL-SIDECAR-MANIFEST-SYNC-V1.md) | OMNL + server-funds-sidecar → manifest | `ura-auto-02`, `ura-auto-05`, `ura-auto-06`, `ura-auto-08` | [UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md](../UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md), [DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](../../../03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md) §7 |
| [TS-SETTLEMENT-INDEXER-MANIFEST-V1.md](TS-SETTLEMENT-INDEXER-MANIFEST-V1.md) | Chain / Rail events → `settlementOrChainRef` | `chain-02`, optional anchoring | [DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md), [DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md](../../../dbis-rail/DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md) |
| [TS-SKR-CUSTODY-ETL-MANIFEST-V1.md](TS-SKR-CUSTODY-ETL-MANIFEST-V1.md) | Custody evidence → manifest | `chain-03` | [SKR_CUSTODY_AUTOMATION_NOTES.md](../SKR_CUSTODY_AUTOMATION_NOTES.md), evidence package schema |
| [TS-GRU-M00-IMPLEMENTATION-PROGRAM-V1.md](TS-GRU-M00-IMPLEMENTATION-PROGRAM-V1.md) | GRU M00 program (strategy → deploy → ops) | `gru-01``gru-06`, `gru-opt-a` | [GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md](../../GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md), [GRU_M00_DIAMOND_FACET_MAP.md](../../GRU_M00_DIAMOND_FACET_MAP.md), [GRU_REGISTRY_WIRING_CHECKLIST.md](../../../runbooks/GRU_REGISTRY_WIRING_CHECKLIST.md) |
| [TS-COMPLIANCE-AUTOMATION-SIGNOFF-V1.md](TS-COMPLIANCE-AUTOMATION-SIGNOFF-V1.md) | Legal / compliance gate for automation | `xc-02` | [INSTITUTION_ONBOARDING_CHARTER.md](../../compliance-matrices/INSTITUTION_ONBOARDING_CHARTER.md), [URA_MANIFEST_WRITER_OPS.md](../../../03-deployment/URA_MANIFEST_WRITER_OPS.md) |
## Conventions
- **MUST / SHOULD / MAY** follow [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) (and [RFC 8174](https://www.rfc-editor.org/rfc/rfc8174) for clarity when BCP 14 is intended).
- **Canonical SoR:** OMNL / Fineract owns `accountingRef`; chain owns settlement attestations only per DBIS Rail design principle ([DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md) §0).
## Related
- [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](../URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -0,0 +1,52 @@
# TS-COMPLIANCE-AUTOMATION-SIGNOFF-V1 — Legal / compliance gate for URA automation
**Version:** 1.0.0
**Last updated:** 2026-04-25
**Status:** Normative for **governance process** (not legal advice).
**Audience:** Legal, compliance, program office, engineering leads.
## 1. Purpose
Ensure **automated** updates to [`manifest.json`](../../../../config/universal-resource-activation/manifest.json) and related evidence fields **remain** within **counsel-approved** obligation coverage in per-jurisdiction compliance matrices.
## 2. Normative references
| Document | Role |
|----------|------|
| [INSTITUTION_ONBOARDING_CHARTER.md](../../compliance-matrices/INSTITUTION_ONBOARDING_CHARTER.md) | Definition of **Complete**, RACI |
| [INSTITUTION_ONBOARDING_PLAYBOOK.md](../../compliance-matrices/INSTITUTION_ONBOARDING_PLAYBOOK.md) | Operational steps |
| [POLICY_PROFILES_REGISTRY.md](../../../../config/universal-resource-activation/POLICY_PROFILES_REGISTRY.md) | Profile version sign-off table |
| [URA_MANIFEST_WRITER_OPS.md](../../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §7 | Memo / ticket template |
## 3. Triggers requiring sign-off
Automation **SHALL NOT** be marked **production-ready** until **all** applicable rows below are satisfied:
| # | Trigger | Owner |
|---|---------|-------|
| T-1 | First production writer for **ledger** (`accountingRef`) | Legal + Compliance |
| T-2 | First production **settlement indexer** (`settlementOrChainRef`) | Legal + Compliance + Risk |
| T-3 | First production **custody ETL** (`evidenceRefs` / custody fields) | Legal + Compliance |
| T-4 | Change to **mapping file** that alters which matrix obligation is evidenced | Legal + Compliance |
| T-5 | Change to **`policyProfileId`** or registry row affecting production resources | Legal + Risk (per registry doc) |
## 4. Evidence package for auditors (recommended content)
Each sign-off **SHOULD** archive:
1. **Matrix reference:** Jurisdiction code + version + row ids (e.g. `ID-OMNL-001`) satisfied by automation.
2. **Field mapping:** Table: automation output field → matrix control id → system of record.
3. **Residual risk:** Known gaps, manual overrides, exception path.
4. **Test artifacts:** Staging E2E logs (see [TS-OMNL-SIDECAR-MANIFEST-SYNC-V1.md](TS-OMNL-SIDECAR-MANIFEST-SYNC-V1.md) §7, [TS-SETTLEMENT-INDEXER-MANIFEST-V1.md](TS-SETTLEMENT-INDEXER-MANIFEST-V1.md) §10).
5. **CI posture:** Whether `URA_STRICT_CLOSURE` / `vars.URA_STRICT_CLOSURE` is enabled for the branch.
## 5. Engineering obligations after sign-off
1. **R-COMP-1:** Manifest automation **MUST** log **immutable** correlation ids (ledger, chain, custody) per technical specs.
2. **R-COMP-2:** Rollback and DR **MUST** be documented ([URA_MANIFEST_WRITER_OPS.md](../../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §8).
3. **R-COMP-3:** Production manifest **SHOULD** pass `pnpm ura:validate-closure:strict` when pilots are closed.
## 6. Related
- [DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../../../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md)
- [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](../URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -0,0 +1,92 @@
# TS-GRU-M00-IMPLEMENTATION-PROGRAM-V1 — GRU M00 diamond implementation program
**Version:** 1.0.0
**Last updated:** 2026-04-25
**Status:** Normative **program** specification (execution phases). Architecture remains in [GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md](../../GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md) and [GRU_M00_DIAMOND_FACET_MAP.md](../../GRU_M00_DIAMOND_FACET_MAP.md).
**Audience:** Solidity leads, governance ops, institutional spec owners.
## 1. Purpose
Turn the **GRU M00 institutional spec + facet map** into a **sequenced, testable delivery program** with explicit decision gates, without duplicating the full facet catalog here.
## 2. Strategy gate (`gru-01`) — MUST complete first
| Decision | Options | Output artifact |
|----------|---------|-----------------|
| **GRC → M00 path** | **Option A:** new diamond · **Option B:** migrate GRC-2535 in place | Signed ADR + pointer in [GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md](../../../runbooks/GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md) §34 |
**R-GRU-0:** No Phase 2 storage layout work **SHALL** begin until **GRC → M00** is recorded and storage collision analysis is approved (see [GRU_M00_DIAMOND_REVIEW_GAPS_AND_RECOMMENDATIONS.md](../../GRU_M00_DIAMOND_REVIEW_GAPS_AND_RECOMMENDATIONS.md) §4.3).
## 3. Storage and governance (`gru-02`)
### 3.1 Deliverables
1. **D-GRU-S-1:** Written **GRUStorage** layout (namespaces, structs, slot discipline) reviewed by Solidity lead.
2. **D-GRU-S-2:** **Governance level** default per environment (dev/test/prod) aligned with [GRU_M00_DIAMOND_FACET_MAP.md](../../GRU_M00_DIAMOND_FACET_MAP.md).
3. **D-GRU-S-3:** **Bitmask / gate** mapping table: which gates invoke for levels 05.
### 3.2 Acceptance
- Forge (or Hardhat) **storage layout** diff shows **no collision** with existing GRC namespaces if Option B.
## 4. Minimum ship spine (`gru-03`)
Per gaps doc §5.1 “minimum ship list”, the program **MUST** deliver callable facets (stubs acceptable where marked):
| Facet class | MUST |
|-------------|------|
| PolicyRouter + gates | Expose entrypoints; emit events or structured reverts for policy violations |
| StandardsRegistryFacet | Register at least one standards module id for tests |
| GovernanceLevelFacet | Read/write level with access control |
| TokenFactory / AssetRegistry path | Register at least one test asset type |
**R-GRU-M-1:** `diamondCut` integration tests **MUST** pass on CI for the scoped tree before testnet deploy.
## 5. Universal asset alignment (`gru-04`)
1. **R-GRU-U-1:** Document **cutover** from `UniversalAssetRegistry` (smom-dbis-138) to M00 registry: mirror vs replace, per [UNIVERSAL_RESOURCE_ONTOLOGY.md](../UNIVERSAL_RESOURCE_ONTOLOGY.md) §Mapping to GRU M00.
2. **R-GRU-U-2:** `resourceId` ↔ on-chain `assetId` mapping **SHOULD** be tabulated in `docs/11-references` or deployment annex when addresses are known.
## 6. Deploy and verify (`gru-05`)
Follow [GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md](../../../runbooks/GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md) §6 verification table.
**Additional MUST for this program:**
1. Record Diamond + facet addresses in [CONTRACT_ADDRESSES_REFERENCE.md](../../../11-references/CONTRACT_ADDRESSES_REFERENCE.md) (or successor inventory).
2. Run **loupe** + **governance level** + **PolicyRouter smoke** on each target chain before “complete” sign-off.
## 7. Governance operations (`gru-06`)
| Control | MUST |
|---------|------|
| Upgrade authority | Multisig or Timelock documented with addresses |
| Pause | Drill once per quarter; RTO documented |
| Incident | Rollback cut procedure documented (runbook §4.3 Option B) |
## 8. Standalone policy anchor (already in repo)
**PolicyProfileRegistry** ([`PolicyProfileRegistry.sol`](../../../../smom-dbis-138/contracts/universal-resource/PolicyProfileRegistry.sol)) **MAY** deploy **before** full M00 spine per [GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md](../../../runbooks/GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md) §7.
**R-GRU-P-1:** Published `contentHash` **MUST** match `pnpm ura:profile-hash <policyProfileId>` for the same JSON canonicalization rule.
## 9. Optional phase — oracle / cross-chain (`gru-opt-a`)
**MAY** follow after Phase 6 stable:
1. Define attestation format for off-chain evidence hashes.
2. Define mirror registry addresses per chain; document in multi-chain deployment annex.
## 10. Program exit criteria (all phases)
| Gate | Condition |
|------|------------|
| **G1** | ADR + storage signed off |
| **G2** | Spine facets on testnet + verification table green |
| **G3** | Mainnet (or Chain 138 prod) addresses recorded + ontology cutover doc updated |
| **G4** | Pause/upgrade drill log archived |
## 11. Related
- [GRU_REGISTRY_WIRING_CHECKLIST.md](../../../runbooks/GRU_REGISTRY_WIRING_CHECKLIST.md)
- [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](../URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -0,0 +1,99 @@
# TS-OMNL-SIDECAR-MANIFEST-SYNC-V1 — OMNL + server-funds-sidecar → URA manifest
**Version:** 1.0.0
**Last updated:** 2026-04-25
**Status:** Normative for implementation (supplements [UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md](../UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md)).
**Audience:** HYBX integration, banking ops, platform SRE.
## 1. Purpose
Define **end-to-end technical requirements** so that:
1. **OMNL / Fineract** remains the **system of record** for ledger postings and `accountingRef`.
2. **`server-funds-sidecar`** exposes **stable, authenticated** APIs (or exports) that correlate treasury actions with OMNL lines.
3. The **URA manifest** receives **non-placeholder** `accountingRef` (and optional quantity) on the correct `resourceId` / `evidencePackageId` rows, validated by `pnpm ura:validate` / `pnpm ura:validate-profiles`.
## 2. Scope and non-goals
### 2.1 In scope
- Correlation model: sidecar draw/hold/release ↔ OMNL journal/batch identifiers.
- Writer / publish pipeline (batch or near-real-time) from SoR exports to manifest fragments.
- Idempotency, observability, and security for the sync path.
- Staging E2E acceptance criteria.
### 2.2 Out of scope (this TS)
- Replacing Fineract as SoR or defining full Fineract product configuration.
- Full OpenAPI for every OMNL deployment variant (this TS defines **required capability classes**; concrete paths MAY be tenant-specific annexes).
- On-chain settlement logic (see [TS-SETTLEMENT-INDEXER-MANIFEST-V1.md](TS-SETTLEMENT-INDEXER-MANIFEST-V1.md)).
## 3. Normative references (answers consolidated from repo)
| Topic | Source |
|-------|--------|
| Sidecar responsibilities (treasury, limits, handoff) | [DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](../../../03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md) §7 `server-funds-sidecar` |
| SoR boundary | [UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md](../UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md) §System-of-record boundary |
| Workstream exit criteria | [DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md](../../../03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md) W1, W2 |
| Mapping file schema | [`omnl-ledger-mapping.v1.schema.json`](../../../../config/universal-resource-activation/integration/omnl-ledger-mapping.v1.schema.json) |
| Fragment builder | [`build-ledger-fragment.mjs`](../../../../scripts/ura/manifest-writer/build-ledger-fragment.mjs) |
| Ops (secrets, publish, DR) | [URA_MANIFEST_WRITER_OPS.md](../../../03-deployment/URA_MANIFEST_WRITER_OPS.md) |
## 4. Definitions
| Term | Definition |
|------|------------|
| **Correlation id** | Stable string linking one sidecar operation to exactly one OMNL posting (or explicitly documented 1:N with parent ref). |
| **Ledger snapshot** | JSON export row (API response or batch file) containing at least the fields referenced by `accountingRefField` in the mapping file. |
| **Manifest fragment** | JSON object with optional `evidencePackages[]` / `resources[]` partial rows, mergeable per [merge-manifest-fragments.mjs](../../../../scripts/ura/merge-manifest-fragments.mjs). |
## 5. Functional requirements
### 5.1 Sidecar → OMNL correlation
The implementation **MUST** satisfy:
1. **R-OMNL-1:** Every **production** draw, hold, or release that affects a URA-tracked `SERVER_FUNDS` pool **MUST** emit or record a **correlation id** retrievable after the fact (log, DB row, or event).
2. **R-OMNL-2:** For each correlation id, operators **MUST** be able to obtain the **OMNL `accountingRef`** (journal entry id, batch id, or institution-agreed composite) that the mapping file can point at.
3. **R-OMNL-3:** If OMNL posting is **asynchronous**, the sidecar **MUST** expose **status** (pending / posted / failed) so the writer does not publish a final `accountingRef` until `posted`.
### 5.2 Manifest writer pipeline
1. **R-WR-1:** The writer **MUST** consume [`omnl-ledger-mapping.v1.json`](../../../../config/universal-resource-activation/integration/omnl-ledger-mapping.v1.example.json) (or equivalent path) validated by `pnpm ura:validate-ledger-mapping`.
2. **R-WR-2:** Before any publish, merged output **MUST** pass `pnpm ura:validate` and `pnpm ura:validate-profiles`.
3. **R-WR-3:** Writes **SHOULD** be **idempotent**: same ledger snapshot + mapping **MUST NOT** create duplicate conflicting evidence rows (use deterministic merge; reject second publish with same `(evidencePackageId, accountingRef)` if policy forbids change).
4. **R-WR-4:** Publish path **MUST** follow one mode documented in [URA_MANIFEST_WRITER_OPS.md](../../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §4 (git PR, secured sync, or future authenticated API).
### 5.3 Phoenix / runtime
1. **R-PHX-1:** Production **SHOULD** set `SERVER_FUNDS_SIDECAR_URL` so [server-funds-sidecar-probe](../../../../phoenix-deploy-api/server.js) returns **200** when the sidecar is healthy (not only 503 unset).
2. **R-PHX-2:** After manifest update, Phoenix **MUST** serve updated JSON from `PHOENIX_REPO_ROOT` or `UNIVERSAL_RESOURCE_MANIFEST_PATH` without manual restart if your deploy model supports file watch; otherwise document reload step.
## 6. Non-functional requirements
| ID | Category | Requirement |
|----|----------|-------------|
| N-S-1 | Security | Fineract and sidecar credentials **MUST NOT** be stored in git; use vault / host env. |
| N-S-2 | Security | Writer service **MUST** use mutual TLS or private network to reach sidecar/OMNL where exposed beyond localhost. |
| N-O-1 | Observability | Emit structured logs: `correlationId`, `resourceId`, `evidencePackageId`, `accountingRef`, manifest git SHA or file version. |
| N-O-2 | Observability | Metric: `ura_manifest_ledger_sync_success_total`, `ura_manifest_ledger_sync_fail_total`, histogram of lag vs OMNL `postedAt`. |
| N-R-1 | Reliability | Failed merge/validate **MUST** land in DLQ or alert; **MUST NOT** partially write corrupt manifest. |
## 7. Staging E2E acceptance (`ura-auto-08`)
The following **MUST** pass in a non-production environment before production automation is enabled:
1. Inject or use a real OMNL posting tied to a test sidecar operation.
2. Produce ledger snapshot JSON; run `pnpm ura:writer:ledger` → fragment.
3. Merge with `merge-manifest-fragments.mjs --out` (or production equivalent).
4. `pnpm ura:validate && pnpm ura:validate-profiles` exit 0.
5. Optional: `pnpm ura:smoke --http` against staging Phoenix shows updated `accountingRef` in served manifest.
## 8. Optional capability annex (informative)
Concrete REST paths for Fineract (`/journalentries`, `/savingstransactions`, etc.) **SHOULD** be recorded in a **tenant annex** (one Markdown or OpenAPI file per OMNL deployment), linked from this TS version header.
## 9. Related
- [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](../URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)
- [URA_PILOT_CLOSURE_RUNBOOK.md](../URA_PILOT_CLOSURE_RUNBOOK.md) §3

View File

@@ -0,0 +1,95 @@
# TS-SETTLEMENT-INDEXER-MANIFEST-V1 — Settlement / MintAuth events → URA manifest
**Version:** 1.0.0
**Last updated:** 2026-04-25
**Status:** Normative for implementation (supplements [DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md) for **off-chain mirror** only).
**Audience:** Chain 138 integrators, indexer operators, platform SRE.
## 1. Purpose
Specify how **on-chain (or ISO-gateway-derived) settlement identifiers** flow into [`settlementOrChainRef`](../../../../config/universal-resource-activation.evidence-package.v1.schema.json) on the correct evidence package rows, using the repos [`build-settlement-fragment.mjs`](../../../../scripts/ura/manifest-writer/build-settlement-fragment.mjs) as the **canonical string format** for v1.
## 2. Design principle (normative)
**Fiat finality and compliance remain off-chain** per DBIS Rail §0. This indexer **MUST NOT** infer good funds from `tx.status` alone; it **MUST** only record **authorization / settlement identifiers** already produced by the Rail / gateway.
## 3. Scope and non-goals
### 3.1 In scope
- Event subscription (logs, websocket, or indexer) → deterministic `settlementOrChainRef` string.
- Reorg handling policy (minimum depth before write).
- Optional: manifest or evidence-package hash anchoring (see §8).
### 3.2 Out of scope
- Replacing MintAuth verification inside contracts.
- Parsing full ISO-20022 payloads on-chain.
## 4. Normative references
| Topic | Source |
|-------|--------|
| Event inventory | [DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md](../../../dbis-rail/DBIS_RAIL_SETTLEMENT_EVENT_SOURCES.md) |
| Rail controls / IDs | [DBIS_RAIL_TECHNICAL_SPEC_V1.md](../../../dbis-rail/DBIS_RAIL_TECHNICAL_SPEC_V1.md) |
| Fragment CLI | [`build-settlement-fragment.mjs`](../../../../scripts/ura/manifest-writer/build-settlement-fragment.mjs) |
## 5. `settlementOrChainRef` format (v1)
Unless a future TS supersedes this, production automation **SHOULD** emit:
```text
messageId=<mintAuthOrGatewayMessageId>;tx=<0x-prefixed-tx-hash>;chain=<decimal-chain-id>
```
Omitted components **MAY** be dropped if not applicable; **MUST NOT** use ambiguous comma-separated free text without `key=` prefixes.
## 6. Functional requirements
### 6.1 Indexer
1. **R-IX-1:** The indexer **MUST** subscribe to a **documented** contract/event set per environment (addresses in deployment annex).
2. **R-IX-2:** Before writing the manifest, the indexer **MUST** wait **N** confirmations (N **SHOULD** default to 12 on Chain 138 unless risk review says otherwise).
3. **R-IX-3:** On reorg deeper than N, the indexer **MUST** emit **alert** and **MUST NOT** silently delete manifest rows without human or policy-governed rollback ([URA_MANIFEST_WRITER_OPS.md](../../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §8).
4. **R-IX-4:** Each processed event **MUST** carry an **idempotency key** `(chainId, blockNumber, logIndex)` or equivalent to prevent duplicate `settlementOrChainRef` appends.
### 6.2 Binding to evidence packages
1. **R-BIND-1:** Configuration **MUST** map `(settlement profile | pool id | message route)``evidencePackageId` (YAML or JSON in secure config, not hard-coded in indexer binary).
2. **R-BIND-2:** If no mapping exists, the indexer **MUST** **fail closed** (alert, no manifest write).
### 6.3 Validation gate
Merged manifest **MUST** pass `pnpm ura:validate` before publish.
## 7. Observability and security
| ID | Requirement |
|----|-------------|
| N-IX-O-1 | Logs **MUST** include `blockNumber`, `txHash`, `evidencePackageId`, idempotency key. |
| N-IX-S-1 | RPC URLs and API keys **MUST** use secrets management. |
| N-IX-S-2 | Indexer write principal **SHOULD** be least-privilege (only manifest publish path, not chain admin). |
## 8. Optional: evidence / manifest anchoring (`chain-opt-a`)
If anchoring is required:
1. Compute `sha256` (or keccak per policy) over canonical JSON of the **evidence package row** (or full manifest).
2. Publish hash via **PolicyProfileRegistry-style** pattern or dedicated anchor contract **MAY** be used; document address in deployment annex.
3. Anchoring **MUST NOT** replace manifest JSON as the operational read model for Phoenix.
## 9. Optional: `keccak(resourceId)` (`chain-opt-b`)
When a GRU or Rail registry facet accepts resource id hashes, use [`keccak-resource-ids.mjs`](../../../../scripts/ura/keccak-resource-ids.mjs) and document the facets expected encoding (UTF-8 string vs ABI-encoded).
## 10. Acceptance criteria (staging)
1. Deployed mock or testnet settlement emits event with known `messageId` / tx.
2. Indexer produces fragment matching §5.
3. After merge + validate, Phoenix GET manifest shows updated `settlementOrChainRef`.
4. Replay same event → no duplicate ref (idempotency).
## 11. Related
- [DBIS_RAIL_JURISDICTION_TRACEABILITY.md](../../../dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md)
- [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](../URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -0,0 +1,71 @@
# TS-SKR-CUSTODY-ETL-MANIFEST-V1 — Custody / SKR evidence → URA manifest
**Version:** 1.0.0
**Last updated:** 2026-04-25
**Status:** Normative for implementation (supplements [SKR_CUSTODY_AUTOMATION_NOTES.md](../SKR_CUSTODY_AUTOMATION_NOTES.md)).
**Audience:** Custody ops, compliance engineering, integration.
## 1. Purpose
Define how **custodian or internal attestation outputs** become **`evidenceRefs`** and evidence-package **`custodyOrSourceEvidence`** fields without weakening jurisdiction matrix obligations ([ID-INDONESIA/banking_v1.md](../../compliance-matrices/ID-INDONESIA/banking_v1.md) or successor).
## 2. Scope and non-goals
### 2.1 In scope
- Data model for custody **artifact** ingestion.
- Hashing, object storage references, and manifest field mapping.
- PII / retention constraints at integration boundary.
- Acceptance tests for Pilot 1 closure path.
### 2.2 Out of scope
- Legal interpretation of custody regulations (counsel-owned).
- Replacing custodians own audit trail.
## 3. Definitions
| Term | Definition |
|------|------------|
| **Artifact** | Statement file, API payload, or signed attestation representing a custody position. |
| **Fingerprint** | Cryptographic digest (SHA-256 **RECOMMENDED**) over canonical bytes of artifact. |
| **External ref** | URI or object key (e.g. `s3://…`, `https://…`) **SHOULD** be paired with fingerprint. |
## 4. Functional requirements
### 4.1 Ingestion
1. **R-SKR-1:** ETL **MUST** accept artifacts only over **authenticated** channels (mTLS, signed webhook, or VPN).
2. **R-SKR-2:** Each artifact **MUST** produce `fingerprint` and **SHOULD** store `retrievedAt` (RFC 3339 UTC).
3. **R-SKR-3:** `evidenceRefs` entries **SHOULD** use **`sha256:<hex>`** or documented URI scheme agreed with audit.
### 4.2 Manifest mapping
1. **R-SKR-4:** Pilot 1 resource (`SKR_SAFEKEEPING`) **MUST** reference the same logical artifact in `evidenceRefs` and in the evidence package row required by [URA_PILOT_CLOSURE_RUNBOOK.md](../URA_PILOT_CLOSURE_RUNBOOK.md) §2.
2. **R-SKR-5:** Updates **MUST** be idempotent per `(resourceId, fingerprint)`.
### 4.3 Evidence package text field
`custodyOrSourceEvidence` **MAY** hold human-readable summary; **MUST** include fingerprint or stable id counsel approved for audit.
## 5. Privacy and retention
1. **N-SKR-P-1:** Personally identifiable data **MUST NOT** be copied into manifest JSON unless explicitly allowed by DPA and matrix.
2. **N-SKR-P-2:** Retention of manifest snapshots **MUST** follow institution policy; DR per [URA_MANIFEST_WRITER_OPS.md](../../../03-deployment/URA_MANIFEST_WRITER_OPS.md) §8.
## 6. Validation
Before production:
1. `pnpm ura:validate` / `pnpm ura:validate-profiles` pass.
2. `pnpm ura:validate-closure:strict` passes **after** placeholders replaced per runbook.
3. Compliance sign-off recorded per [TS-COMPLIANCE-AUTOMATION-SIGNOFF-V1.md](TS-COMPLIANCE-AUTOMATION-SIGNOFF-V1.md).
## 7. Implementation note
A dedicated `build-custody-fragment.mjs` **MAY** be added mirroring the ledger writer; until then, fragments **MAY** be hand-crafted JSON matching merge rules in [merge-manifest-fragments.mjs](../../../../scripts/ura/merge-manifest-fragments.mjs).
## 8. Related
- [UNIVERSAL_RESOURCE_SKR_CUSTODY_LANE.md](../UNIVERSAL_RESOURCE_SKR_CUSTODY_LANE.md)
- [UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md](../UNIVERSAL_RESOURCE_EVIDENCE_PACKAGE.md)

View File

@@ -102,7 +102,7 @@
| **00-meta** (tasks, next steps, phases) | [00-meta/NEXT_STEPS_INDEX.md](00-meta/NEXT_STEPS_INDEX.md), [00-meta/PHASES_AND_TASKS_MASTER.md](00-meta/PHASES_AND_TASKS_MASTER.md) |
| **02-architecture** | [02-architecture/](02-architecture/) — **client / division terminology:** [02-architecture/CLIENT_DIVISION_TERMINOLOGY.md](02-architecture/CLIENT_DIVISION_TERMINOLOGY.md); **Public sector + Phoenix catalog baseline:** [02-architecture/PUBLIC_SECTOR_TENANCY_MARKETPLACE_AND_DEPLOYMENT_BASELINE.md](02-architecture/PUBLIC_SECTOR_TENANCY_MARKETPLACE_AND_DEPLOYMENT_BASELINE.md); **non-goals (incl. catalog vs marketing §9):** [02-architecture/NON_GOALS.md](02-architecture/NON_GOALS.md); **DeFi Oracle Meta Mainnet (Chain 138):** [dbis_chain_138_technical_master_plan.md](../dbis_chain_138_technical_master_plan.md), [02-architecture/DBIS_NODE_ROLE_MATRIX.md](02-architecture/DBIS_NODE_ROLE_MATRIX.md), [02-architecture/DBIS_PHASE2_PROXMOX_SOVEREIGNIZATION_ROADMAP.md](02-architecture/DBIS_PHASE2_PROXMOX_SOVEREIGNIZATION_ROADMAP.md) |
| **03-deployment** | [03-deployment/OPERATIONAL_RUNBOOKS.md](03-deployment/OPERATIONAL_RUNBOOKS.md), [03-deployment/DEPLOYMENT_ORDER_OF_OPERATIONS.md](03-deployment/DEPLOYMENT_ORDER_OF_OPERATIONS.md), **Public sector live checklist:** [03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md](03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md), **Proxmox VE ops template:** [03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md](03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md) · [`config/proxmox-operational-template.json`](config/proxmox-operational-template.json); **DBIS Phase 13:** [03-deployment/PHASE1_DISCOVERY_RUNBOOK.md](03-deployment/PHASE1_DISCOVERY_RUNBOOK.md), [03-deployment/DBIS_PHASE3_E2E_PRODUCTION_SIMULATION_RUNBOOK.md](03-deployment/DBIS_PHASE3_E2E_PRODUCTION_SIMULATION_RUNBOOK.md), [03-deployment/CALIPER_CHAIN138_PERF_HOOK.md](03-deployment/CALIPER_CHAIN138_PERF_HOOK.md), [03-deployment/DBIS_HYPERLEDGER_RUNTIME_STATUS.md](03-deployment/DBIS_HYPERLEDGER_RUNTIME_STATUS.md), [03-deployment/DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md](03-deployment/DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md), **RTGS canonical production checklist and institutional-finance layers:** [03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md), [03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md](03-deployment/DBIS_RTGS_MASTER_PLAN_IMPLEMENTATION_TRACKER.md), [03-deployment/DBIS_RTGS_FX_TRANSACTION_CATALOG.md](03-deployment/DBIS_RTGS_FX_TRANSACTION_CATALOG.md), [03-deployment/DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md](03-deployment/DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md), [03-deployment/DBIS_RTGS_FX_AND_LIQUIDITY_OPERATING_MODEL.md](03-deployment/DBIS_RTGS_FX_AND_LIQUIDITY_OPERATING_MODEL.md), [03-deployment/DBIS_RTGS_CONTROL_PLANE_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_CONTROL_PLANE_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_RTGS_LATER_PHASE_SIDECARS_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_LATER_PHASE_SIDECARS_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md), [03-deployment/DBIS_RTGS_FIRST_SLICE_ARCHITECTURE.md](03-deployment/DBIS_RTGS_FIRST_SLICE_ARCHITECTURE.md), [03-deployment/DBIS_RTGS_FIRST_SLICE_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_FIRST_SLICE_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md](03-deployment/DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md), [03-deployment/DBIS_MOJALOOP_INTEGRATION_STATUS.md](03-deployment/DBIS_MOJALOOP_INTEGRATION_STATUS.md), [03-deployment/DBIS_HYPERLEDGER_IDENTITY_STACK_DECISION.md](03-deployment/DBIS_HYPERLEDGER_IDENTITY_STACK_DECISION.md) |
| **04-configuration** | [04-configuration/README.md](04-configuration/README.md), [04-configuration/ADDITIONAL_PATHS_AND_EXTENSIONS.md](04-configuration/ADDITIONAL_PATHS_AND_EXTENSIONS.md) (paths, registry, token-mapping, LiFi/Jumper); **Multi-jurisdiction compliance (matrices, charter, playbook):** [04-configuration/compliance-matrices/README.md](04-configuration/compliance-matrices/README.md), [04-configuration/jurisdictions/JURISDICTION_CATALOG.md](04-configuration/jurisdictions/JURISDICTION_CATALOG.md), [`config/jurisdictions/catalog.v1.json`](../config/jurisdictions/catalog.v1.json), [dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md](dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md); **Universal resource activation (SKR, server funds, infra):** [04-configuration/universal-resource-activation/README.md](04-configuration/universal-resource-activation/README.md), [UNIVERSAL_RESOURCE_WIRING.md](04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md), `pnpm ura:validate`, `pnpm ura:validate-profiles`, `pnpm ura:merge-manifest`, `pnpm ura:validate-closure` / `URA_STRICT_CLOSURE`, `pnpm ura:smoke`, `node scripts/ura/keccak-resource-ids.mjs`, Phoenix URA routes (manifest, policy-profiles, sidecar-probe), [`config/universal-resource-activation/manifest.json`](../config/universal-resource-activation/manifest.json), [`config/universal-resource-activation/policy-profiles.json`](../config/universal-resource-activation/policy-profiles.json), [manifest-fragments/README.md](../config/universal-resource-activation/manifest-fragments/README.md); **Chain 138 wallets:** [04-configuration/CHAIN138_WALLET_CONFIG_VALIDATION.md](04-configuration/CHAIN138_WALLET_CONFIG_VALIDATION.md); **Chain 2138 testnet wallets:** [04-configuration/CHAIN2138_WALLET_CONFIG_VALIDATION.md](04-configuration/CHAIN2138_WALLET_CONFIG_VALIDATION.md); **OMNL Indonesia / HYBX-BATCH-001:** [04-configuration/mifos-omnl-central-bank/HYBX_BATCH_001_OPERATOR_CHECKLIST.md](04-configuration/mifos-omnl-central-bank/HYBX_BATCH_001_OPERATOR_CHECKLIST.md), [04-configuration/mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md](04-configuration/mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md) |
| **04-configuration** | [04-configuration/README.md](04-configuration/README.md), [04-configuration/ADDITIONAL_PATHS_AND_EXTENSIONS.md](04-configuration/ADDITIONAL_PATHS_AND_EXTENSIONS.md) (paths, registry, token-mapping, LiFi/Jumper); **Multi-jurisdiction compliance (matrices, charter, playbook):** [04-configuration/compliance-matrices/README.md](04-configuration/compliance-matrices/README.md), [04-configuration/jurisdictions/JURISDICTION_CATALOG.md](04-configuration/jurisdictions/JURISDICTION_CATALOG.md), [`config/jurisdictions/catalog.v1.json`](../config/jurisdictions/catalog.v1.json), [dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md](dbis-rail/DBIS_RAIL_JURISDICTION_TRACEABILITY.md); **Universal resource activation (SKR, server funds, infra):** [04-configuration/universal-resource-activation/README.md](04-configuration/universal-resource-activation/README.md), [UNIVERSAL_RESOURCE_WIRING.md](04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md), [URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md](04-configuration/universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md), [technical-specs/README.md](04-configuration/universal-resource-activation/technical-specs/README.md) (normative TS-* for remaining implementation), [URA_MANIFEST_WRITER_OPS.md](03-deployment/URA_MANIFEST_WRITER_OPS.md), [GRU_REGISTRY_WIRING_CHECKLIST.md](runbooks/GRU_REGISTRY_WIRING_CHECKLIST.md), `pnpm ura:*`, Phoenix URA routes, [`config/universal-resource-activation/`](../config/universal-resource-activation/); **Chain 138 wallets:** [04-configuration/CHAIN138_WALLET_CONFIG_VALIDATION.md](04-configuration/CHAIN138_WALLET_CONFIG_VALIDATION.md); **Chain 2138 testnet wallets:** [04-configuration/CHAIN2138_WALLET_CONFIG_VALIDATION.md](04-configuration/CHAIN2138_WALLET_CONFIG_VALIDATION.md); **OMNL Indonesia / HYBX-BATCH-001:** [04-configuration/mifos-omnl-central-bank/HYBX_BATCH_001_OPERATOR_CHECKLIST.md](04-configuration/mifos-omnl-central-bank/HYBX_BATCH_001_OPERATOR_CHECKLIST.md), [04-configuration/mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md](04-configuration/mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md) |
| **Phoenix / Sankofa deploy handoff** | [04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md](04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md) — live CTs, env locations, secret split, rotate/reload/verify commands |
| **06-besu** | [06-besu/MASTER_INDEX.md](06-besu/MASTER_INDEX.md) |
| **Testnet (2138)** | [testnet/DEFI_ORACLE_META_TESTNET_2138_RUNBOOK.md](testnet/DEFI_ORACLE_META_TESTNET_2138_RUNBOOK.md), [testnet/TESTNET_DEPLOYMENT.md](testnet/TESTNET_DEPLOYMENT.md) |

View File

@@ -2,7 +2,7 @@
**Network:** DBIS Mainnet (ChainID 138)
**Document type:** Control verification checklist (pre-audit)
**Companion documents:** [Technical Spec v1](DBIS_RAIL_TECHNICAL_SPEC_V1.md), [Rulebook v1](DBIS_RAIL_RULEBOOK_V1.md), [Security Threat Model v1](DBIS_RAIL_SECURITY_THREAT_MODEL_V1.md), [Regulator Brief v1](DBIS_RAIL_REGULATOR_BRIEF_V1.md)
**Companion documents:** [Technical Spec v1](DBIS_RAIL_TECHNICAL_SPEC_V1.md), [Rulebook v1](DBIS_RAIL_RULEBOOK_V1.md), [Security Threat Model v1](DBIS_RAIL_SECURITY_THREAT_MODEL_V1.md), [Regulator Brief v1](DBIS_RAIL_REGULATOR_BRIEF_V1.md), [Jurisdiction traceability](DBIS_RAIL_JURISDICTION_TRACEABILITY.md) (controls ↔ per-jurisdiction compliance matrices ↔ URA policy profiles)
**Purpose:** Bridge documentation to operational evidence. Each item is verifiable (code, config, procedure, or test). Use this checklist before external audit or formal control mapping.

View File

@@ -35,6 +35,20 @@ Section numbers refer to the respective document sections (e.g. Spec 6.5 = DBIS_
---
## Jurisdiction matrices and policy profiles
Obligations in **per-jurisdiction compliance matrices** map to these control IDs where the Rail is in scope. Full obligation → control → `policyProfileId` → URA field mapping lives in **[DBIS_RAIL_JURISDICTION_TRACEABILITY.md](DBIS_RAIL_JURISDICTION_TRACEABILITY.md)**.
| Artifact | Role |
|----------|------|
| [compliance-matrices/README.md](../04-configuration/compliance-matrices/README.md) | Index of jurisdiction folders (ID, stubs, drafts). |
| [policy-profiles.json](../../config/universal-resource-activation/policy-profiles.json) | Machine-readable `policyProfileId` registry with `minimumGruGovernanceLevel`. |
| [POLICY_PROFILES_REGISTRY.md](../../config/universal-resource-activation/POLICY_PROFILES_REGISTRY.md) | Doc control and legal sign-off table for profile versions. |
When a jurisdiction adds **local** controls (prefix e.g. `J-ID-AML-001`), document them in that jurisdictions matrix and extend the traceability doc; they do not replace C1C18 for on-chain Rail behavior.
---
## References
- **Spec:** [DBIS_RAIL_TECHNICAL_SPEC_V1.md](DBIS_RAIL_TECHNICAL_SPEC_V1.md)

View File

@@ -0,0 +1,42 @@
# DBIS Rail — jurisdiction and compliance matrix traceability
**Last updated:** 2026-04-25
**Purpose:** Cross-link [DBIS_RAIL_CONTROL_MAPPING_V1.md](DBIS_RAIL_CONTROL_MAPPING_V1.md) controls to **jurisdiction compliance matrices** and **URA policy profiles**, so auditors can navigate: **obligation (matrix row) → Rail control → profile → evidence**.
**Not legal advice.** Matrix obligation text must be counsel-approved per jurisdiction.
---
## Rail controls → jurisdiction artifacts (starter mapping)
| Control ID | Rail / ops intent | Example jurisdiction matrix rows | Policy profile(s) | Evidence / manifest fields |
|------------|-------------------|----------------------------------|-------------------|----------------------------|
| C1 | Mint path restricted to SettlementRouter | ID-RAIL-001 | `server_funds_treasury_v1` | `settlementOrChainRef` |
| C2 | Owner mint revoked / GRU pattern | ID-RAIL-001 | `server_funds_treasury_v1`, `institutional_custody_skr_v1` | On-chain config + evidence package |
| C3C6 | EIP-712, replay, quorum, signers | ID-RAIL-001 | `server_funds_treasury_v1` | MintAuth / messageId |
| C7 | Signer allowlist / revocation | ID-OMNL-001, ID-SIDECAR-001 | all production profiles | Ops attestations |
| C8 | Deterministic accountingRef | ID-OMNL-001 | `server_funds_treasury_v1` | `accountingRef` |
| C9 | Evidence bundle hashed (isoHash) | ID-ISO-001, ID-SKR-001 | all | `custodyOrSourceEvidence`, ISO package |
| C10 | messageId / accountingRef / mint 1:1 | ID-RAIL-001 | `server_funds_treasury_v1` | Evidence package closure |
| C11C15 | Router safety, caps, pause, corridor, suspension | ID-RAIL-001, ID-SIDECAR-001 | `server_funds_treasury_v1` | Rail + sidecar monitoring |
| C16 | Validator segregation | ID-RAIL-001 (infra) | `infra_capacity_ops_v1` | Ops runbooks |
| C17 | Good funds and finality | ID-OMNL-001, ID-SIDECAR-001 | `server_funds_treasury_v1` | Rulebook alignment + ledger |
| C18 | Documentation versioning | (program-wide) | registry in [policy-profiles.json](../../config/universal-resource-activation/policy-profiles.json) | Doc control tables |
**Indonesia matrix row ids** reference [ID-INDONESIA/banking_v1.md](../04-configuration/compliance-matrices/ID-INDONESIA/banking_v1.md).
**US-DELAWARE-CORP-STUB** is a draft second-jurisdiction exercise only ([README](../04-configuration/compliance-matrices/US-DELAWARE-CORP-STUB/README.md)); do not use its row ids in production traceability until counsel replaces the stub.
---
## Audit checklist cross-reference
When updating [DBIS_RAIL_AUDIT_READINESS_CHECKLIST_V1.md](DBIS_RAIL_AUDIT_READINESS_CHECKLIST_V1.md), add **jurisdiction matrix id** and **policyProfileId** to each sections evidence appendix where a jurisdiction-specific obligation applies.
---
## Related
- [DBIS_RAIL_CONTROL_MAPPING_V1.md](DBIS_RAIL_CONTROL_MAPPING_V1.md)
- [INSTITUTION_ONBOARDING_CHARTER.md](../04-configuration/compliance-matrices/INSTITUTION_ONBOARDING_CHARTER.md)
- [URA_PILOT_CLOSURE_RUNBOOK.md](../04-configuration/universal-resource-activation/URA_PILOT_CLOSURE_RUNBOOK.md)

View File

@@ -0,0 +1,33 @@
# DBIS Rail — settlement event sources for URA `settlementOrChainRef`
**Last updated:** 2026-04-25
**Purpose:** Inventory of where **MintAuth / settlement** identifiers originate so an indexer or batch job can populate [`manifest.json`](../../config/universal-resource-activation/manifest.json) evidence fields (`settlementOrChainRef`).
**Not exhaustive** — align field names with [`DBIS_RAIL_TECHNICAL_SPEC_V1.md`](DBIS_RAIL_TECHNICAL_SPEC_V1.md) and your deployed contracts in `smom-dbis-138`.
## 1. On-chain (EVM)
| Source | What to capture | Notes |
|--------|-----------------|--------|
| **Settlement / router events** | `messageId`, optional `accountingRef` echo | Subscribe via WebSocket or `eth_getLogs` with tuned filters. |
| **Transaction receipt** | `tx.hash`, `blockNumber`, `chainId` | Compose ref: `messageId=…;tx=…;chain=…` (see [`build-settlement-fragment.mjs`](../../scripts/ura/manifest-writer/build-settlement-fragment.mjs)). |
| **Indexed subgraph** | Same fields | If you run Graph Node / Ponder, expose a stable query for “last settlement for resource X”. |
## 2. Off-chain / ISO path
| Source | What to capture |
|--------|-----------------|
| ISO-20022 gateway / `dbis_core` | Business message id, end-to-end id, or gateway correlation id stored when mint authorized. |
Store the chosen id in `settlementOrChainRef` and document the format in the evidence package `explanation` until a single canonical encoding is enforced.
## 3. Wire-up checklist
1. Pick authoritative source per environment (Chain 138 vs testnet).
2. Implement listener → call writer (`build-settlement-fragment`) → merge → validate → publish.
3. Add alert if no settlement event within SLA for an open `reconciliationStatus`.
## Related
- [`URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md`](../04-configuration/universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)
- [`DBIS_RAIL_JURISDICTION_TRACEABILITY.md`](DBIS_RAIL_JURISDICTION_TRACEABILITY.md)

View File

@@ -106,7 +106,13 @@ Add Forge or Hardhat tests for facet upgrade and storage consistency when the sp
---
## 7. Related documents
## 7. Standalone URA policy anchor (prefull M00)
Before the full M00 spine is live, you can deploy **`PolicyProfileRegistry`** in `smom-dbis-138` to anchor `policyProfileId` content hashes on-chain (`pnpm ura:profile-hash` in the proxmox repo). See [GRU_REGISTRY_WIRING_CHECKLIST.md](GRU_REGISTRY_WIRING_CHECKLIST.md) §6 and `contracts/universal-resource/PolicyProfileRegistry.sol`.
---
## 8. Related documents
- [GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md](../04-configuration/GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md) — §1§8, default governance level, event signatures appendix.
- [GRU_M00_DIAMOND_FACET_MAP.md](../04-configuration/GRU_M00_DIAMOND_FACET_MAP.md) — Facet map, governance levels 05.
@@ -114,3 +120,4 @@ Add Forge or Hardhat tests for facet upgrade and storage consistency when the sp
- [MULTI_CHAIN_EXECUTION_DETERMINISTIC_DEPLOYMENT.md](MULTI_CHAIN_EXECUTION_DETERMINISTIC_DEPLOYMENT.md) — CREATE2 factory and salts.
- [CONTRACT_DEPLOYMENT_RUNBOOK.md](../03-deployment/CONTRACT_DEPLOYMENT_RUNBOOK.md) — General deployment and env.
- [gru-docs/contracts/README.md](../gru-docs/contracts/README.md) — GRC-2535 Diamond (Option B migration source).
- [GRU_REGISTRY_WIRING_CHECKLIST.md](GRU_REGISTRY_WIRING_CHECKLIST.md) — URA + GRU wiring checklist (includes PolicyProfileRegistry).

View File

@@ -0,0 +1,57 @@
# GRU / on-chain registry wiring checklist
**Last updated:** 2026-04-25
**Purpose:** Operationalize URA + GRU alignment: diamond strategy, storage, facets, deployment, governance, **standalone PolicyProfileRegistry** (in `smom-dbis-138`), and optional hardening.
**Specs:** [GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md](../04-configuration/GRU_M00_DIAMOND_INSTITUTIONAL_SPEC.md) · [GRU_M00_DIAMOND_FACET_MAP.md](../04-configuration/GRU_M00_DIAMOND_FACET_MAP.md) · [GRU_M00_DIAMOND_REVIEW_GAPS_AND_RECOMMENDATIONS.md](../04-configuration/GRU_M00_DIAMOND_REVIEW_GAPS_AND_RECOMMENDATIONS.md) · [GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md](GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md)
## 1. Strategy (gru-01)
- [ ] Decide **Option A** (new M00 diamond) vs **Option B** (migrate GRC-2535) per deployment runbook §34.
- [ ] Record decision + approvers in deployment ticket.
## 2. Storage and governance model (gru-02)
- [ ] Finalize GRUStorage namespaces (no collision with GRC if migrating).
- [ ] Document governance level defaults per env (dev 0, prod ≥2).
## 3. Minimum ship facets (gru-03)
- [ ] PolicyRouter + Compliance/Accounting gate stubs (or full implementations).
- [ ] StandardsRegistryFacet + GovernanceLevelFacet.
- [ ] TokenFactory / AssetRegistry path per spec.
## 4. Universal asset alignment (gru-04)
- [ ] Map `UniversalAssetRegistry` / token lists to future `assetId` — see [UNIVERSAL_RESOURCE_ONTOLOGY.md](../04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_ONTOLOGY.md) §Mapping to GRU M00.
## 5. Deploy, verify, ops (gru-05 / gru-06)
- [ ] Follow [GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md](GRU_M00_DIAMOND_DEPLOYMENT_RUNBOOK.md) §6 verification table.
- [ ] Multisig / Timelock on `diamondCut` and policy changes.
- [ ] Pause drill documented and executed once per quarter.
## 6. Policy profile on-chain anchor (gru-07) — **standalone contract (shipped)**
| Step | Command / action |
|------|------------------|
| Unit test | `cd smom-dbis-138 && FORGE_SCOPE=universal-resource bash scripts/forge/scope.sh test --match-contract PolicyProfileRegistryTest` |
| Content hash | `pnpm ura:profile-hash <policyProfileId>` (proxmox repo root) |
| Deploy | `forge script script/universal-resource/DeployPolicyProfileRegistry.s.sol:DeployPolicyProfileRegistry --rpc-url $RPC_URL_138 --broadcast` (set `PRIVATE_KEY`, optional `POLICY_PROFILE_REGISTRY_ADMIN`) |
| Publish | Call `publishProfile(policyProfileId, contentHash, version, effectiveFrom)` with `PUBLISHER_ROLE` |
Contract: [`smom-dbis-138/contracts/universal-resource/PolicyProfileRegistry.sol`](../../smom-dbis-138/contracts/universal-resource/PolicyProfileRegistry.sol)
## 7. Optional (gru-opt-a)
- [ ] Oracle or attestation bridge for off-chain evidence hashes.
- [ ] Cross-chain registry mirror addresses.
## 8. Doc handoff (gru-08)
- [ ] Record deployed `PolicyProfileRegistry` address in [CONTRACT_ADDRESSES_REFERENCE](../11-references/CONTRACT_ADDRESSES_REFERENCE.md) when live.
- [ ] Link from [UNIVERSAL_RESOURCE_WIRING.md](../04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md) §5.
## Related
- [`URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md`](../04-configuration/universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -25,6 +25,17 @@
"test:basic": "cd mcp-proxmox && node test-basic-tools.js",
"test:workflows": "cd mcp-proxmox && node test-workflows.js",
"verify:ws-chain138": "node scripts/verify-ws-rpc-chain138.mjs",
"ura:validate": "node scripts/validate/validate-universal-resource-activation.mjs",
"ura:validate-profiles": "node scripts/validate/validate-ura-policy-profiles.mjs",
"ura:validate-closure": "node scripts/ura/validate-manifest-closure.mjs",
"ura:validate-closure:strict": "node scripts/ura/validate-manifest-closure.mjs --strict",
"ura:merge-manifest": "node scripts/ura/merge-manifest-fragments.mjs",
"ura:validate-ledger-mapping": "node scripts/validate/validate-omnl-ledger-mapping.mjs",
"ura:writer:ledger": "node scripts/ura/manifest-writer/build-ledger-fragment.mjs",
"ura:writer:settlement": "node scripts/ura/manifest-writer/build-settlement-fragment.mjs",
"ura:profile-hash": "node scripts/ura/policy-profiles-content-hash.mjs",
"ura:keccak": "node scripts/ura/keccak-resource-ids.mjs",
"ura:smoke": "bash scripts/verify/smoke-universal-resource-activation.sh",
"mission-control:dev": "pnpm --filter mission-control dev",
"mission-control:build": "pnpm --filter mission-control build",
"mission-control:start": "pnpm --filter mission-control start",

View File

@@ -32,8 +32,15 @@ PHOENIX_PARTNER_KEYS=
# Optional: override path for GET /api/v1/public-sector/programs (else bundled copy, repo config/, or ../config/)
PUBLIC_SECTOR_MANIFEST_PATH=
# Optional: URA manifest for GET /api/v1/universal-resource-activation/manifest
UNIVERSAL_RESOURCE_MANIFEST_PATH=
# Optional: URA policy profile registry for GET /api/v1/universal-resource-activation/policy-profiles
#UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH=
# Optional: proxmox repo root on host (manifest = $PHOENIX_REPO_ROOT/config/public-sector-program-manifest.json)
PHOENIX_REPO_ROOT=/home/intlc/projects/proxmox
# Optional: server-funds-sidecar base URL for GET /api/v1/universal-resource-activation/server-funds-sidecar-probe
#SERVER_FUNDS_SIDECAR_URL=http://192.168.x.x:8080
#SERVER_FUNDS_SIDECAR_HEALTH_PATH=/actuator/health
# Gitea "cloudflare-sync" deploy target: allow scripts/deployment/gitea-cloudflare-sync.sh to call Cloudflare (1/true)
#PHOENIX_CLOUDFLARE_SYNC=0
# Optional zone for that sync: CLOUDFLARE_GITEA_SYNC_ZONE=d-bis.org

View File

@@ -19,9 +19,11 @@ Gitea webhook receiver and deploy endpoint for Gitea → Phoenix / Proxmox deplo
| GET | /api/v1/health/summary | Aggregated health for Portal |
| GET | /api/v1/public-sector/programs | Public-sector / eIDAS program manifest (JSON; **no API key**) |
| GET | /api/v1/universal-resource-activation/manifest | Universal resource activation store: resources, evidence, profile refs (JSON; **no API key**) — see [docs/04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md](../docs/04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md) |
| GET | /api/v1/universal-resource-activation/policy-profiles | URA policy profile registry: `policy-profiles.json` (JSON; **no API key**) |
| GET | /api/v1/universal-resource-activation/server-funds-sidecar-probe | Optional: proxy health check to `SERVER_FUNDS_SIDECAR_URL` (**no API key**; 503 if URL unset) |
| GET | /health | Health check |
All `/api/v1/*` routes except **`GET /api/v1/public-sector/programs`** and **`GET /api/v1/universal-resource-activation/manifest`** accept optional partner API key when `PHOENIX_PARTNER_KEYS` is set (`X-API-Key` or `Authorization: Bearer <key>`).
All `/api/v1/*` routes except **`GET /api/v1/public-sector/programs`**, **`GET /api/v1/universal-resource-activation/manifest`**, **`GET /api/v1/universal-resource-activation/policy-profiles`**, and **`GET /api/v1/universal-resource-activation/server-funds-sidecar-probe`** accept optional partner API key when `PHOENIX_PARTNER_KEYS` is set (`X-API-Key` or `Authorization: Bearer <key>`). The same public path list is defined as `PUBLIC_V1_NO_PARTNER_KEY_PATHS` in [`server.js`](server.js) (keep in sync when adding a new unauthenticated read).
## Environment
@@ -48,10 +50,13 @@ Copy `.env.example` to `.env` and set `GITEA_TOKEN` (and optionally `PHOENIX_DEP
| PHOENIX_PARTNER_KEYS | | Comma-separated API keys for /api/v1/* (optional) |
| PUBLIC_SECTOR_MANIFEST_PATH | | Override JSON path for `/api/v1/public-sector/programs` |
| UNIVERSAL_RESOURCE_MANIFEST_PATH | | Override JSON path for `/api/v1/universal-resource-activation/manifest` (default: `config/universal-resource-activation/manifest.json` under `PHOENIX_REPO_ROOT` or `../config/…`) |
| UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH | | Override JSON path for `/api/v1/universal-resource-activation/policy-profiles` (default: `config/universal-resource-activation/policy-profiles.json` under repo root) |
| SERVER_FUNDS_SIDECAR_URL | | Base URL for `/api/v1/universal-resource-activation/server-funds-sidecar-probe` (e.g. `http://<host>:8080`); if unset, probe returns 503 with hint |
| SERVER_FUNDS_SIDECAR_HEALTH_PATH | | Optional first path to try (e.g. `/actuator/health`); also tries `/actuator/health`, `/health`, `/api/health` |
| PHOENIX_REPO_ROOT | | Proxmox repo root; loads `config/public-sector-program-manifest.json` if present |
| DEPLOY_TARGETS_PATH | | Override deploy target file; default is `phoenix-deploy-api/deploy-targets.json` |
**URA smoke (proxmox repo):** `bash scripts/verify/smoke-universal-resource-activation.sh` validates the manifest with JSON Schema; add `--http` and set `PHOENIX_BASE_URL` (e.g. `http://127.0.0.1:4001`) to assert this API returns 200. See [UNIVERSAL_RESOURCE_WIRING.md](../docs/04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md) §2.1.
**URA smoke (proxmox repo):** `bash scripts/verify/smoke-universal-resource-activation.sh` validates the manifest with JSON Schema; add `--http` and set `PHOENIX_BASE_URL` to also GET `/api/v1/universal-resource-activation/manifest`, `/api/v1/universal-resource-activation/policy-profiles`, and `/api/v1/universal-resource-activation/server-funds-sidecar-probe` (503 + `configured: false` is OK if `SERVER_FUNDS_SIDECAR_URL` is unset). See [UNIVERSAL_RESOURCE_WIRING.md](../docs/04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md) §2.1.
**Program manifest:** From a full repo checkout, the file is `config/public-sector-program-manifest.json`. `scripts/install-systemd.sh` copies it next to `server.js` on `/opt/phoenix-deploy-api` so the endpoint works without a full tree.

View File

@@ -123,6 +123,50 @@ paths:
'500': { description: Invalid JSON or read error }
'503': { description: Manifest file not found }
/api/v1/universal-resource-activation/policy-profiles:
get:
tags: [UniversalResource]
summary: URA policy profile registry (JSON)
description: |
Serves `config/universal-resource-activation/policy-profiles.json` (machine-readable profiles + GRU levels).
Override with `UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH`. No API key required. Returns 503 if the file is missing.
responses:
'200':
description: Policy profile registry JSON
content:
application/json:
schema:
type: object
properties:
schemaVersion: { type: string }
updatedAt: { type: string }
profiles: { type: array, items: { type: object } }
'500': { description: Invalid JSON or read error }
'503': { description: Registry file not found }
/api/v1/universal-resource-activation/server-funds-sidecar-probe:
get:
tags: [UniversalResource]
summary: Optional health probe to server-funds-sidecar
description: |
If `SERVER_FUNDS_SIDECAR_URL` is set, tries `/actuator/health`, `/health`, `/api/health` (or `SERVER_FUNDS_SIDECAR_HEALTH_PATH`).
No API key. Returns 503 with hint when the env var is unset; 200 when a path returns 2xx with JSON or body.
responses:
'200':
description: Sidecar responded 2xx on a candidate path
content:
application/json:
schema:
type: object
properties:
configured: { type: boolean }
baseUrl: { type: string }
healthPath: { type: string }
status: { type: integer }
'500': { description: Server error when handling the probe }
'502': { description: All candidate paths failed or non-2xx }
'503': { description: SERVER_FUNDS_SIDECAR_URL not set }
/api/v1/infra/nodes:
get:
tags: [Infra]

View File

@@ -11,6 +11,8 @@
* GET /api/v1/ve/vms/:node/:vmid/status — VM/CT status
* GET /api/v1/public-sector/programs — Public-sector / eIDAS program manifest (JSON)
* GET /api/v1/universal-resource-activation/manifest — Universal resource activation manifest (JSON; no secret)
* GET /api/v1/universal-resource-activation/policy-profiles — URA policy profile registry JSON (no secret)
* GET /api/v1/universal-resource-activation/server-funds-sidecar-probe — Optional health proxy to server-funds-sidecar (no secret; 503 if URL unset)
* GET /health — Health check
*
* Env: PORT, GITEA_URL, GITEA_TOKEN, PHOENIX_DEPLOY_SECRET
@@ -47,6 +49,18 @@ const PROXMOX_TOKEN_NAME = process.env.PROXMOX_TOKEN_NAME || '';
const PROXMOX_TOKEN_VALUE = process.env.PROXMOX_TOKEN_VALUE || '';
const hasProxmox = PROXMOX_HOST && PROXMOX_TOKEN_NAME && PROXMOX_TOKEN_VALUE;
const VE_LIFECYCLE_ENABLED = process.env.PHOENIX_VE_LIFECYCLE_ENABLED === '1' || process.env.PHOENIX_VE_LIFECYCLE_ENABLED === 'true';
const SERVER_FUNDS_SIDECAR_URL = (process.env.SERVER_FUNDS_SIDECAR_URL || '').trim();
/**
* GET paths that skip partner API key — each route must be registered *before* `app.use('/api/v1', partnerKeyMiddleware)`.
* Keep in sync with docs (AGENTS, phoenix-deploy-api README, OpenAPI) when adding a new public /api/v1 read.
*/
const PUBLIC_V1_NO_PARTNER_KEY_PATHS = [
'/api/v1/public-sector/programs',
'/api/v1/universal-resource-activation/manifest',
'/api/v1/universal-resource-activation/policy-profiles',
'/api/v1/universal-resource-activation/server-funds-sidecar-probe',
];
const PROMETHEUS_URL = (process.env.PROMETHEUS_URL || 'http://localhost:9090').replace(/\/$/, '');
const PHOENIX_WEBHOOK_URL = process.env.PHOENIX_WEBHOOK_URL || '';
@@ -101,6 +115,23 @@ function resolveUniversalResourceManifestPath() {
return path.join(__dirname, '..', 'config', 'universal-resource-activation', 'manifest.json');
}
/**
* URA policy profile registry (policy-profiles.json).
* 1) UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH
* 2) PHOENIX_REPO_ROOT / PROXMOX_REPO_PATH + config/universal-resource-activation/policy-profiles.json
* 3) ../config/...
*/
function resolveUniversalResourcePolicyProfilesPath() {
const override = (process.env.UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH || '').trim();
if (override && existsSync(override)) return override;
const repoRoot = (process.env.PHOENIX_REPO_ROOT || process.env.PROXMOX_REPO_PATH || '').trim().replace(/\/$/, '');
if (repoRoot) {
const fromRepo = path.join(repoRoot, 'config', 'universal-resource-activation', 'policy-profiles.json');
if (existsSync(fromRepo)) return fromRepo;
}
return path.join(__dirname, '..', 'config', 'universal-resource-activation', 'policy-profiles.json');
}
function resolveDeployTargetsPath() {
const override = (process.env.DEPLOY_TARGETS_PATH || '').trim();
if (override && existsSync(override)) return override;
@@ -711,6 +742,89 @@ app.get('/api/v1/universal-resource-activation/manifest', (req, res) => {
}
});
/**
* GET /api/v1/universal-resource-activation/policy-profiles — URA policy profile registry (JSON; no secret).
*/
app.get('/api/v1/universal-resource-activation/policy-profiles', (req, res) => {
const registryPath = resolveUniversalResourcePolicyProfilesPath();
try {
if (!existsSync(registryPath)) {
return res.status(503).json({
error: 'Policy profile registry not found',
path: registryPath,
hint: 'Set UNIVERSAL_RESOURCE_POLICY_PROFILES_PATH or deploy with config/universal-resource-activation/policy-profiles.json under PHOENIX_REPO_ROOT',
});
}
const raw = readFileSync(registryPath, 'utf8');
const data = JSON.parse(raw);
res.type('application/json').json(data);
} catch (err) {
res.status(500).json({ error: err.message, path: registryPath });
}
});
/**
* GET /api/v1/universal-resource-activation/server-funds-sidecar-probe — forward probe to server-funds-sidecar when SERVER_FUNDS_SIDECAR_URL is set.
* No API key. Returns 503 with hint when unset (operator LAN / VM path per pilot plan).
*/
app.get('/api/v1/universal-resource-activation/server-funds-sidecar-probe', async (req, res) => {
if (!SERVER_FUNDS_SIDECAR_URL) {
return res.status(503).json({
configured: false,
error: 'SERVER_FUNDS_SIDECAR_URL not set',
hint: 'Set to base URL (e.g. http://<rtgs-funds-host>:8080) to probe /actuator/health or /health. See UNIVERSAL_RESOURCE_WIRING.md and UNIVERSAL_RESOURCE_SERVER_FUNDS_LANE.md.',
});
}
const base = SERVER_FUNDS_SIDECAR_URL.replace(/\/$/, '');
const extra = (process.env.SERVER_FUNDS_SIDECAR_HEALTH_PATH || '').trim();
const candidates = [];
if (extra) candidates.push(extra.startsWith('/') ? extra : `/${extra}`);
for (const p of ['/actuator/health', '/health', '/api/health']) {
if (!candidates.includes(p)) candidates.push(p);
}
const attempts = [];
for (const p of candidates) {
if (!p.startsWith('/')) continue;
const url = `${base}${p}`;
const controller = new AbortController();
const t = setTimeout(() => controller.abort(), 8000);
try {
const r = await fetch(url, {
signal: controller.signal,
headers: { Accept: 'application/json, text/plain, */*' },
});
const text = await r.text();
let body;
try {
body = JSON.parse(text);
} catch {
body = { raw: text.length > 4000 ? `${text.slice(0, 4000)}` : text };
}
if (r.ok) {
clearTimeout(t);
return res.json({
configured: true,
baseUrl: base,
healthPath: p,
status: r.status,
body,
});
}
attempts.push({ path: p, status: r.status });
} catch (err) {
attempts.push({ path: p, error: err.message || String(err) });
} finally {
clearTimeout(t);
}
}
return res.status(502).json({
configured: true,
baseUrl: base,
error: 'All server-funds-sidecar health paths failed or returned non-2xx',
attempts,
});
});
app.use('/api/v1', partnerKeyMiddleware);
/**
@@ -937,12 +1051,17 @@ app.listen(PORT, () => {
if (PHOENIX_WEBHOOK_URL) console.log('Outbound webhook enabled:', PHOENIX_WEBHOOK_URL);
if (WEBHOOK_DEPLOY_ENABLED) console.log('Inbound webhook deploy execution enabled');
if (PARTNER_KEYS.length > 0) {
console.log('Partner API key auth enabled for /api/v1/* (except GET /api/v1/public-sector/programs and GET /api/v1/universal-resource-activation/manifest)');
console.log('Partner API key auth: /api/v1/* except', PUBLIC_V1_NO_PARTNER_KEY_PATHS.join(', '));
}
const mpath = resolvePublicSectorManifestPath();
const urapath = resolveUniversalResourceManifestPath();
const uraprof = resolveUniversalResourcePolicyProfilesPath();
const dpath = resolveDeployTargetsPath();
console.log(`Public-sector manifest: ${mpath} (${existsSync(mpath) ? 'ok' : 'missing'})`);
console.log(`URA manifest: ${urapath} (${existsSync(urapath) ? 'ok' : 'missing'})`);
console.log(`URA policy-profiles: ${uraprof} (${existsSync(uraprof) ? 'ok' : 'missing'})`);
if (SERVER_FUNDS_SIDECAR_URL) {
console.log('Server-funds sidecar probe target:', SERVER_FUNDS_SIDECAR_URL);
}
console.log(`Deploy targets: ${dpath} (${existsSync(dpath) ? 'ok' : 'missing'})`);
});

View File

@@ -204,7 +204,7 @@ CT 2301 (besu-rpc-private-1) may fail to start with `lxc.hook.pre-start` due to
- **Daily/weekly checks:** `./scripts/maintenance/daily-weekly-checks.sh [daily|weekly|all]` — explorer sync (135), RPC health (136), config API (137). **Cron:** `./scripts/maintenance/schedule-daily-weekly-cron.sh [--install|--show]` (daily 08:00, weekly Sun 09:00). See [OPERATIONAL_RUNBOOKS.md](../docs/03-deployment/OPERATIONAL_RUNBOOKS.md) § Maintenance.
- **Start firefly-ali-1 (6201):** `./scripts/maintenance/start-firefly-6201.sh [--dry-run] [--host HOST]` — start CT 6201 on r630-02 when needed (optional ongoing).
- **Config validation (pre-deploy):** `./scripts/validation/validate-config-files.sh` — set `VALIDATE_REQUIRED_FILES` for required paths. **CI / all validation:** `./scripts/verify/run-all-validation.sh [--skip-genesis] [--json-out reports/status/run-all-validation-latest.json]` — dependencies, config files, **cW\* mesh matrix** (merge of `cross-chain-pmm-lps/config/deployment-status.json` and `reports/extraction/promod-uniswap-v2-live-pair-discovery-latest.json` when that file exists; no RPC), optional genesis (no LAN/SSH). **Matrix only:** `./scripts/verify/build-cw-mesh-deployment-matrix.sh` — stdout markdown; `--json-out reports/status/cw-mesh-deployment-matrix-latest.json` for machine-readable rows. **URA (universal resource activation) smoke:** `./scripts/verify/smoke-universal-resource-activation.sh` (JSON Schema only) or the same with `--http` and optional `PHOENIX_BASE_URL` to assert Phoenix `GET /api/v1/universal-resource-activation/manifest`; see `docs/04-configuration/universal-resource-activation/UNIVERSAL_RESOURCE_WIRING.md` §2.1.
- **Config validation (pre-deploy):** `./scripts/validation/validate-config-files.sh` — set `VALIDATE_REQUIRED_FILES` for required paths. **CI / all validation:** `./scripts/verify/run-all-validation.sh [--skip-genesis] [--json-out reports/status/run-all-validation-latest.json]` — dependencies, config files, **cW\* mesh matrix** (merge of `cross-chain-pmm-lps/config/deployment-status.json` and `reports/extraction/promod-uniswap-v2-live-pair-discovery-latest.json` when that file exists; no RPC), optional genesis (no LAN/SSH). **Matrix only:** `./scripts/verify/build-cw-mesh-deployment-matrix.sh` — stdout markdown; `--json-out reports/status/cw-mesh-deployment-matrix-latest.json` for machine-readable rows. **URA (universal resource activation):** **`pnpm ura:validate`**, **`pnpm ura:validate-profiles`**, **`pnpm ura:merge-manifest`**, **`pnpm ura:validate-ledger-mapping`**, **`pnpm ura:writer:ledger`**, **`pnpm ura:writer:settlement`**, **`pnpm ura:profile-hash`**, **`pnpm ura:validate-closure`** / **`pnpm ura:validate-closure:strict`**, **`pnpm ura:keccak`**, **`pnpm ura:smoke`**. Optional **`URA_STRICT_CLOSURE=1`**. Tracker: `docs/04-configuration/universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md`. See `UNIVERSAL_RESOURCE_WIRING.md` §2.1 and §5; multi-jurisdiction: `docs/04-configuration/compliance-matrices/README.md`.
- **Wrapper summaries:** `./scripts/run-completable-tasks-from-anywhere.sh --json-out reports/status/run-completable-tasks-latest.json`, `./scripts/run-e2e-flow-tasks-full-parallel.sh --json-out reports/status/run-e2e-flow-tasks-latest.json`, `./scripts/deployment/run-all-next-steps-chain138.sh --json-out reports/status/run-all-next-steps-chain138-latest.json`, and `./scripts/run-all-operator-tasks-from-lan.sh --json-out reports/status/run-all-operator-tasks-latest.json` produce machine-readable step summaries that match the terminal progress output.
### 13. Phase 2, 3 & 4 Deployment Scripts

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env node
/**
* Emit keccak256(utf8(resourceId)) for each row in the URA manifest.
* Use when anchoring resourceId in on-chain / GRU registries (operator step; not automatic mirroring).
*
* Usage: from repo root — node scripts/ura/keccak-resource-ids.mjs
* Requires: root devDependency `ethers` (v6).
*/
import { readFileSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { keccak256, toUtf8Bytes } from 'ethers';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.join(__dirname, '../..');
const manifestPath = path.join(projectRoot, 'config', 'universal-resource-activation', 'manifest.json');
if (!existsSync(manifestPath)) {
console.error(`[keccak-ura] Missing ${manifestPath}`);
process.exit(1);
}
const m = JSON.parse(readFileSync(manifestPath, 'utf8'));
const resources = m.resources || [];
console.log(
'# keccak256(utf8(resourceId)) for universal-resource-activation resources\n# Use for optional on-chain / GRU registry rows; keep manifest as canonical off-chain store.\n',
);
for (const r of resources) {
const id = r.resourceId;
if (typeof id !== 'string' || !id) continue;
const h = keccak256(toUtf8Bytes(id));
console.log(id);
console.log(` ${h}`);
console.log('');
}
console.log(`[keccak-ura] ${resources.length} resource(s)`);

View File

@@ -0,0 +1,134 @@
#!/usr/bin/env node
/**
* Shared URA manifest validation (schemas + cross-checks).
* Used by validate-universal-resource-activation.mjs and merge-manifest-fragments.mjs.
*/
import { readFileSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export function getProjectRoot() {
return path.resolve(path.join(__dirname, '..', '..', '..'));
}
export function getDefaultManifestPath(projectRoot = getProjectRoot()) {
return path.join(projectRoot, 'config', 'universal-resource-activation', 'manifest.json');
}
/**
* @returns {{ validateManifest: import('ajv').ValidateFunction, validateResource: import('ajv').ValidateFunction, validateEvidence: import('ajv').ValidateFunction, ajv: import('ajv').default }}
*/
export function loadUraManifestValidators(projectRoot = getProjectRoot()) {
const manifestSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.manifest.v1.schema.json');
const resourceSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.resource.v1.schema.json');
const evidenceSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.evidence-package.v1.schema.json');
const ajv = new Ajv({
allErrors: true,
strict: false,
validateSchema: false,
});
addFormats(ajv);
const manifestSchema = JSON.parse(readFileSync(manifestSchemaPath, 'utf8'));
const resourceSchema = JSON.parse(readFileSync(resourceSchemaPath, 'utf8'));
const evidenceSchema = JSON.parse(readFileSync(evidenceSchemaPath, 'utf8'));
return {
validateManifest: ajv.compile(manifestSchema),
validateResource: ajv.compile(resourceSchema),
validateEvidence: ajv.compile(evidenceSchema),
ajv,
};
}
/**
* @param {unknown} data
* @param {{ validateManifest: import('ajv').ValidateFunction, validateResource: import('ajv').ValidateFunction, validateEvidence: import('ajv').ValidateFunction }} validators
* @returns {string[]} empty if valid
*/
export function validateUraManifestData(data, validators) {
const errors = [];
const { validateManifest, validateResource, validateEvidence, ajv } = validators;
if (!validateManifest(data)) {
return [`Manifest failed manifest schema: ${ajv.errorsText(validateManifest.errors, { separator: '\n' })}`];
}
if (!Array.isArray(data.resources)) {
return ['resources must be an array'];
}
if (!Array.isArray(data.evidencePackages)) {
return ['evidencePackages must be an array'];
}
data.resources.forEach((r, i) => {
if (!validateResource(r)) {
errors.push(
`resources[${i}] (resourceId=${r?.resourceId}): ${ajv.errorsText(validateResource.errors, { separator: '\n' })}`
);
}
});
data.evidencePackages.forEach((p, i) => {
if (!validateEvidence(p)) {
errors.push(
`evidencePackages[${i}] (id=${p?.evidencePackageId}): ${ajv.errorsText(validateEvidence.errors, { separator: '\n' })}`
);
}
});
if (errors.length) return errors;
const ids = new Set(data.resources.map((r) => r.resourceId).filter(Boolean));
data.evidencePackages.forEach((p, pi) => {
(p.resourceIds || []).forEach((rid) => {
if (!ids.has(rid)) {
errors.push(`evidencePackages[${pi}] references unknown resourceId: ${rid}`);
}
});
});
return errors;
}
/**
* CLI-style: read file, validate, log, exit 0 or 1.
* @param {string} [manifestPath]
*/
export function validateUraManifestFileCli(manifestPath) {
const projectRoot = getProjectRoot();
const pathToUse = manifestPath || getDefaultManifestPath(projectRoot);
function fail(msg) {
console.error(`[validate-ura] ${msg}`);
process.exit(1);
}
if (!existsSync(pathToUse)) {
fail(`Missing ${pathToUse}`);
}
let data;
try {
data = JSON.parse(readFileSync(pathToUse, 'utf8'));
} catch (e) {
fail(`Invalid JSON: ${e.message}`);
}
const validators = loadUraManifestValidators(projectRoot);
const errs = validateUraManifestData(data, validators);
if (errs.length) {
errs.forEach((e) => console.error(`[validate-ura] ${e}`));
process.exit(1);
}
console.log(
`[validate-ura] OK: ${data.resources.length} resource(s), ${data.evidencePackages.length} evidence package(s)`
);
process.exit(0);
}

View File

@@ -0,0 +1,36 @@
# URA manifest writer (ledger + settlement fragments)
**Purpose:** Build **partial manifest fragments** from machine-readable inputs so ops or a batch job can merge them (`pnpm ura:merge-manifest` or manual paste) after validation.
## Ledger → `accountingRef`
1. Define mapping: [`omnl-ledger-mapping.v1.example.json`](../../../config/universal-resource-activation/integration/omnl-ledger-mapping.v1.example.json) → copy to `omnl-ledger-mapping.v1.json` (gitignored or secured).
2. Export ledger snapshot JSON (Fineract/OMNL/sidecar ETL).
3. Run:
```bash
pnpm ura:writer:ledger -- \
--mapping config/universal-resource-activation/integration/omnl-ledger-mapping.v1.example.json \
--ledger config/universal-resource-activation/integration/examples/ledger-snapshot.example.json
```
4. Pipe output into a file under `manifest-fragments/` or merge with `merge-manifest-fragments.mjs --out`.
Validate mapping: `pnpm ura:validate-ledger-mapping -- config/.../omnl-ledger-mapping.v1.example.json`
## Rail / chain → `settlementOrChainRef`
```bash
pnpm ura:writer:settlement -- \
--evidence-package-id ura:pilot:evidence-register-bootstrap \
--message-id 0xabc \
--tx-hash 0xdef \
--chain-id 138
```
Emits a fragment with a single `evidencePackages[]` row (shallow merge by id).
## Related
- [`URA_MANIFEST_WRITER_OPS.md`](../../../docs/03-deployment/URA_MANIFEST_WRITER_OPS.md)
- [`URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md`](../../../docs/04-configuration/universal-resource-activation/URA_MANIFEST_AUTOMATION_IMPLEMENTATION_TRACKER.md)

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env node
/**
* Build a manifest fragment from a ledger snapshot JSON + omnl-ledger-mapping.v1.json
* See scripts/ura/manifest-writer/README.md
*/
import { readFileSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { getByPath, asString } from './lib/get-by-path.mjs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.join(__dirname, '..', '..', '..');
function parseArgs() {
const a = process.argv.slice(2);
const o = {};
for (let i = 0; i < a.length; i++) {
if (a[i] === '--mapping') o.mapping = a[++i];
else if (a[i] === '--ledger') o.ledger = a[++i];
}
return o;
}
const args = parseArgs();
const mappingPath = path.resolve(projectRoot, args.mapping || 'config/universal-resource-activation/integration/omnl-ledger-mapping.v1.example.json');
const ledgerPath = path.resolve(
projectRoot,
args.ledger || 'config/universal-resource-activation/integration/examples/ledger-snapshot.example.json'
);
for (const p of [mappingPath, ledgerPath]) {
if (!existsSync(p)) {
console.error(`[writer-ledger] Missing file: ${p}`);
process.exit(1);
}
}
let mapping;
let ledger;
try {
mapping = JSON.parse(readFileSync(mappingPath, 'utf8'));
ledger = JSON.parse(readFileSync(ledgerPath, 'utf8'));
} catch (e) {
console.error(`[writer-ledger] JSON error: ${e.message}`);
process.exit(1);
}
const evidencePackages = [];
for (const row of mapping.evidencePackages || []) {
const pkg = { evidencePackageId: row.evidencePackageId };
if (row.accountingRefField) {
const v = getByPath(ledger, row.accountingRefField);
pkg.accountingRef = asString(v);
}
evidencePackages.push(pkg);
}
const resources = [];
for (const ru of mapping.resourceUpdates || []) {
const v = getByPath(ledger, ru.quantityField);
resources.push({
resourceId: ru.resourceId,
quantity: asString(v),
});
}
const fragment = {};
if (evidencePackages.length) fragment.evidencePackages = evidencePackages;
if (resources.length) fragment.resources = resources;
process.stdout.write(`${JSON.stringify(fragment, null, 2)}\n`);

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env node
/**
* Build a manifest fragment with settlementOrChainRef on an evidence package.
*/
function parseArgs() {
const a = process.argv.slice(2);
const o = {};
for (let i = 0; i < a.length; i++) {
if (a[i] === '--evidence-package-id') o.evidencePackageId = a[++i];
else if (a[i] === '--message-id') o.messageId = a[++i];
else if (a[i] === '--tx-hash') o.txHash = a[++i];
else if (a[i] === '--chain-id') o.chainId = a[++i];
}
return o;
}
const args = parseArgs();
if (!args.evidencePackageId) {
console.error('[writer-settlement] Required: --evidence-package-id');
process.exit(1);
}
const parts = [];
if (args.messageId) parts.push(`messageId=${args.messageId}`);
if (args.txHash) parts.push(`tx=${args.txHash}`);
if (args.chainId) parts.push(`chain=${args.chainId}`);
const settlementOrChainRef = parts.length ? parts.join(';') : '';
const fragment = {
evidencePackages: [
{
evidencePackageId: args.evidencePackageId,
settlementOrChainRef,
},
],
};
process.stdout.write(`${JSON.stringify(fragment, null, 2)}\n`);

View File

@@ -0,0 +1,25 @@
/**
* @param {Record<string, unknown>} obj
* @param {string} dotPath e.g. "a.b.c"
* @returns {unknown}
*/
export function getByPath(obj, dotPath) {
if (!dotPath || typeof dotPath !== 'string') return undefined;
const parts = dotPath.split('.').filter(Boolean);
let cur = obj;
for (const p of parts) {
if (cur == null || typeof cur !== 'object') return undefined;
cur = /** @type {Record<string, unknown>} */ (cur)[p];
}
return cur;
}
/**
* @param {unknown} v
* @returns {string}
*/
export function asString(v) {
if (v == null) return '';
if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return String(v);
return JSON.stringify(v);
}

View File

@@ -0,0 +1,162 @@
#!/usr/bin/env node
/**
* Merge optional JSON fragments into the URA manifest and validate (dry-run or --out).
*
* Fragments: partial objects with optional keys resources[], evidencePackages[], policyProfileRefs[].
* Later files in sort order override same resourceId / evidencePackageId.
*
* Usage (repo root):
* node scripts/ura/merge-manifest-fragments.mjs
* node scripts/ura/merge-manifest-fragments.mjs --out /tmp/merged-manifest.json
* node scripts/ura/merge-manifest-fragments.mjs --base config/universal-resource-activation/manifest.json --fragments-dir config/universal-resource-activation/manifest-fragments
*/
import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
import path from 'path';
import {
getProjectRoot,
getDefaultManifestPath,
loadUraManifestValidators,
validateUraManifestData,
} from './lib/validate-ura-manifest.mjs';
function parseArgs() {
const argv = process.argv.slice(2);
const out = {};
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
if (a === '--out') out.out = argv[++i];
else if (a === '--base') out.base = argv[++i];
else if (a === '--fragments-dir') out.fragmentsDir = argv[++i];
}
return out;
}
function deepClone(o) {
return JSON.parse(JSON.stringify(o));
}
function profileKey(ref) {
if (!ref || typeof ref.id !== 'string') return null;
const v = ref.version != null ? String(ref.version) : '';
return `${ref.id}@${v}`;
}
function mergeFragment(base, frag, fragmentLabel) {
const issues = [];
if (frag.policyProfileRefs && Array.isArray(frag.policyProfileRefs)) {
const map = new Map();
(base.policyProfileRefs || []).forEach((r) => {
const k = profileKey(r);
if (k) map.set(k, r);
});
frag.policyProfileRefs.forEach((r) => {
const k = profileKey(r);
if (k) map.set(k, r);
});
base.policyProfileRefs = [...map.values()].sort((a, b) => {
const ka = profileKey(a);
const kb = profileKey(b);
return ka.localeCompare(kb);
});
}
if (frag.resources && Array.isArray(frag.resources)) {
const byId = new Map((base.resources || []).map((r) => [r.resourceId, r]));
frag.resources.forEach((r) => {
if (!r || typeof r.resourceId !== 'string') {
issues.push(`${fragmentLabel}: skip resource without resourceId`);
return;
}
issues.push(
`${fragmentLabel}: ${byId.has(r.resourceId) ? 'replace' : 'add'} resource ${r.resourceId}`
);
byId.set(r.resourceId, { ...(byId.get(r.resourceId) || {}), ...r });
});
base.resources = [...byId.values()].sort((a, b) => String(a.resourceId).localeCompare(String(b.resourceId)));
}
if (frag.evidencePackages && Array.isArray(frag.evidencePackages)) {
const byId = new Map((base.evidencePackages || []).map((p) => [p.evidencePackageId, p]));
frag.evidencePackages.forEach((p) => {
if (!p || typeof p.evidencePackageId !== 'string') {
issues.push(`${fragmentLabel}: skip evidence package without evidencePackageId`);
return;
}
issues.push(
`${fragmentLabel}: ${byId.has(p.evidencePackageId) ? 'replace' : 'add'} evidencePackage ${p.evidencePackageId}`
);
const prev = byId.get(p.evidencePackageId) || {};
byId.set(p.evidencePackageId, { ...prev, ...p });
});
base.evidencePackages = [...byId.values()].sort((a, b) =>
String(a.evidencePackageId).localeCompare(String(b.evidencePackageId))
);
}
return issues;
}
function main() {
const args = parseArgs();
const projectRoot = getProjectRoot();
const basePath = path.resolve(projectRoot, args.base || getDefaultManifestPath(projectRoot));
const fragmentsDir = path.resolve(
projectRoot,
args.fragmentsDir || path.join('config', 'universal-resource-activation', 'manifest-fragments')
);
if (!existsSync(basePath)) {
console.error(`[merge-ura-manifest] Missing base: ${basePath}`);
process.exit(1);
}
let merged;
try {
merged = JSON.parse(readFileSync(basePath, 'utf8'));
} catch (e) {
console.error(`[merge-ura-manifest] Invalid base JSON: ${e.message}`);
process.exit(1);
}
const mergeNotes = [];
if (existsSync(fragmentsDir)) {
const files = readdirSync(fragmentsDir)
.filter((f) => f.endsWith('.json') && !f.startsWith('_'))
.sort();
for (const f of files) {
const fp = path.join(fragmentsDir, f);
let frag;
try {
frag = JSON.parse(readFileSync(fp, 'utf8'));
} catch (e) {
console.error(`[merge-ura-manifest] Invalid JSON in ${fp}: ${e.message}`);
process.exit(1);
}
mergeNotes.push(...mergeFragment(merged, frag, f));
}
}
const validators = loadUraManifestValidators(projectRoot);
const errs = validateUraManifestData(merged, validators);
if (errs.length) {
errs.forEach((e) => console.error(`[merge-ura-manifest] ${e}`));
process.exit(1);
}
mergeNotes.forEach((n) => console.log(`[merge-ura-manifest] ${n}`));
console.log(
`[merge-ura-manifest] OK: ${merged.resources.length} resource(s), ${merged.evidencePackages.length} evidence package(s)`
);
if (args.out) {
writeFileSync(path.resolve(args.out), `${JSON.stringify(merged, null, 2)}\n`, 'utf8');
console.log(`[merge-ura-manifest] Wrote ${path.resolve(args.out)}`);
} else {
console.log('[merge-ura-manifest] Dry-run (pass --out <file> to write merged JSON)');
}
process.exit(0);
}
main();

View File

@@ -0,0 +1,46 @@
#!/usr/bin/env node
/**
* Compute a content hash for one policy profile row (for PolicyProfileRegistry.publishProfile on-chain).
* Uses keccak256(utf8(canonicalJson)) where canonicalJson is stable key-sorted JSON of the profile object.
*
* Usage: node scripts/ura/policy-profiles-content-hash.mjs <policyProfileId>
*/
import { readFileSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { keccak256, toUtf8Bytes } from 'ethers';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.join(__dirname, '..', '..');
const registryPath = path.join(projectRoot, 'config/universal-resource-activation/policy-profiles.json');
const id = process.argv[2];
if (!id) {
console.error('Usage: node scripts/ura/policy-profiles-content-hash.mjs <policyProfileId>');
process.exit(1);
}
if (!existsSync(registryPath)) {
console.error(`Missing ${registryPath}`);
process.exit(1);
}
const data = JSON.parse(readFileSync(registryPath, 'utf8'));
const profile = (data.profiles || []).find((p) => p.policyProfileId === id);
if (!profile) {
console.error(`Unknown policyProfileId: ${id}`);
process.exit(1);
}
function sortKeys(obj) {
if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) return obj;
const out = {};
for (const k of Object.keys(obj).sort()) {
out[k] = sortKeys(obj[k]);
}
return out;
}
const canonical = JSON.stringify(sortKeys(profile));
const hash = keccak256(toUtf8Bytes(canonical));
console.log(JSON.stringify({ policyProfileId: id, contentHash: hash, canonicalBytes: canonical.length }, null, 2));

View File

@@ -0,0 +1,81 @@
#!/usr/bin/env node
/**
* Optional production gate: fail if manifest still contains pilot placeholders or open reconciliation.
*
* Usage (repo root):
* node scripts/ura/validate-manifest-closure.mjs # warnings only, exit 0
* node scripts/ura/validate-manifest-closure.mjs --strict # exit 1 on violations
*
* CI: set URA_STRICT_CLOSURE=1 and run validate-config-files.sh (see script header there).
*/
import { readFileSync, existsSync } from 'fs';
import { getProjectRoot, getDefaultManifestPath } from './lib/validate-ura-manifest.mjs';
const PILOT_PARTICIPANT = /ura:participant:pilot-/i;
const PENDING_EVIDENCE = /^ura:evidence:pending-/i;
const TBD_RE = /\bTBD\b/i;
const strict = process.argv.includes('--strict');
const projectRoot = getProjectRoot();
const manifestPath = getDefaultManifestPath(projectRoot);
function main() {
const log = (m) => console.log(`[validate-ura-closure] ${m}`);
const warn = (m) => console.warn(`[validate-ura-closure] WARN: ${m}`);
const err = (m) => console.error(`[validate-ura-closure] ${strict ? 'FAIL' : 'WARN'}: ${m}`);
if (!existsSync(manifestPath)) {
console.error(`[validate-ura-closure] Missing ${manifestPath}`);
process.exit(1);
}
let data;
try {
data = JSON.parse(readFileSync(manifestPath, 'utf8'));
} catch (e) {
console.error(`[validate-ura-closure] Invalid JSON: ${e.message}`);
process.exit(1);
}
const violations = [];
(data.resources || []).forEach((r, i) => {
const pid = r.ownerParticipantId;
if (typeof pid === 'string' && PILOT_PARTICIPANT.test(pid)) {
violations.push(`resources[${i}] ownerParticipantId is pilot placeholder: ${pid}`);
}
(r.evidenceRefs || []).forEach((ref, j) => {
if (typeof ref === 'string' && PENDING_EVIDENCE.test(ref)) {
violations.push(`resources[${i}] evidenceRefs[${j}] pending: ${ref}`);
}
});
});
(data.evidencePackages || []).forEach((p, i) => {
if (p.reconciliationStatus === 'open') {
violations.push(`evidencePackages[${i}] (${p.evidencePackageId}) reconciliationStatus is open`);
}
const checkFields = ['custodyOrSourceEvidence', 'accountingRef', 'settlementOrChainRef', 'deploymentRef', 'explanation'];
for (const f of checkFields) {
const v = p[f];
if (typeof v === 'string' && TBD_RE.test(v)) {
violations.push(`evidencePackages[${i}] (${p.evidencePackageId}).${f} contains TBD`);
}
}
});
if (violations.length === 0) {
log('OK: no pilot/TBD/open-reconciliation patterns detected');
process.exit(0);
}
violations.forEach((v) => (strict ? err : warn)(v));
if (strict) {
err(`${violations.length} violation(s) — close pilots per URA_PILOT_CLOSURE_RUNBOOK.md`);
process.exit(1);
}
log(`${violations.length} notice(s) (use --strict to fail CI)`);
process.exit(0);
}
main();

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env node
/**
* Validate omnl-ledger-mapping.v1.json against omnl-ledger-mapping.v1.schema.json
* Usage: node scripts/validate/validate-omnl-ledger-mapping.mjs [path]
*/
import { readFileSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.join(__dirname, '../..');
const defaultPath = path.join(
projectRoot,
'config/universal-resource-activation/integration/omnl-ledger-mapping.v1.example.json'
);
const schemaPath = path.join(
projectRoot,
'config/universal-resource-activation/integration/omnl-ledger-mapping.v1.schema.json'
);
const file = path.resolve(projectRoot, process.argv[2] || defaultPath);
if (!existsSync(file)) {
console.error(`[validate-ledger-mapping] Missing ${file}`);
process.exit(1);
}
if (!existsSync(schemaPath)) {
console.error(`[validate-ledger-mapping] Missing schema ${schemaPath}`);
process.exit(1);
}
const ajv = new Ajv({ allErrors: true, strict: false, validateSchema: false });
addFormats(ajv);
const validate = ajv.compile(JSON.parse(readFileSync(schemaPath, 'utf8')));
let data;
try {
data = JSON.parse(readFileSync(file, 'utf8'));
} catch (e) {
console.error(`[validate-ledger-mapping] Invalid JSON: ${e.message}`);
process.exit(1);
}
if (!validate(data)) {
console.error(`[validate-ledger-mapping] FAIL: ${ajv.errorsText(validate.errors, { separator: '\n' })}`);
process.exit(1);
}
console.log(`[validate-ledger-mapping] OK: ${file}`);
process.exit(0);

View File

@@ -1,100 +1,10 @@
#!/usr/bin/env node
/**
* Validate config/universal-resource-activation/manifest.json against
* - universal-resource-activation.manifest.v1.schema.json
* - universal-resource-activation.resource.v1.schema.json (per item in resources[])
* - universal-resource-activation.evidence-package.v1.schema.json (per item in evidencePackages[])
* Validate config/universal-resource-activation/manifest.json against URA JSON Schemas.
*
* Usage: from repo root: node scripts/validate/validate-universal-resource-activation.mjs
* Exit 0 on success, 1 on error.
* Usage: from repo root: node scripts/validate/validate-universal-resource-activation.mjs [path/to/manifest.json]
*/
import { readFileSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
import { validateUraManifestFileCli } from '../ura/lib/validate-ura-manifest.mjs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.join(__dirname, '../..');
const configDir = path.join(projectRoot, 'config', 'universal-resource-activation');
const manifestPath = path.join(configDir, 'manifest.json');
const manifestSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.manifest.v1.schema.json');
const resourceSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.resource.v1.schema.json');
const evidenceSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.evidence-package.v1.schema.json');
function fail(msg) {
console.error(`[validate-ura] ${msg}`);
process.exit(1);
}
if (!existsSync(manifestPath)) {
fail(`Missing ${manifestPath}`);
}
const ajv = new Ajv({
allErrors: true,
strict: false,
validateSchema: false,
});
addFormats(ajv);
const manifestSchema = JSON.parse(readFileSync(manifestSchemaPath, 'utf8'));
const resourceSchema = JSON.parse(readFileSync(resourceSchemaPath, 'utf8'));
const evidenceSchema = JSON.parse(readFileSync(evidenceSchemaPath, 'utf8'));
const validateManifest = ajv.compile(manifestSchema);
const validateResource = ajv.compile(resourceSchema);
const validateEvidence = ajv.compile(evidenceSchema);
const raw = readFileSync(manifestPath, 'utf8');
let data;
try {
data = JSON.parse(raw);
} catch (e) {
fail(`Invalid JSON: ${e.message}`);
}
if (!validateManifest(data)) {
fail(`Manifest failed manifest schema: ${ajv.errorsText(validateManifest.errors, { separator: '\n' })}`);
}
if (!Array.isArray(data.resources)) {
fail('resources must be an array');
}
if (!Array.isArray(data.evidencePackages)) {
fail('evidencePackages must be an array');
}
data.resources.forEach((r, i) => {
if (!validateResource(r)) {
fail(
`resources[${i}] (resourceId=${r?.resourceId}): ${ajv.errorsText(validateResource.errors, { separator: '\n' })}`
);
}
});
data.evidencePackages.forEach((p, i) => {
if (!validateEvidence(p)) {
fail(
`evidencePackages[${i}] (id=${p?.evidencePackageId}): ${ajv.errorsText(validateEvidence.errors, { separator: '\n' })}`
);
}
});
// Cross-check: all resourceIds referenced in evidence exist
const ids = new Set(data.resources.map((r) => r.resourceId).filter(Boolean));
data.evidencePackages.forEach((p, pi) => {
(p.resourceIds || []).forEach((rid) => {
if (!ids.has(rid)) {
fail(
`evidencePackages[${pi}] references unknown resourceId: ${rid}`
);
}
});
});
console.log(
`[validate-ura] OK: ${data.resources.length} resource(s), ${data.evidencePackages.length} evidence package(s)`
);
process.exit(0);
const arg = process.argv[2];
validateUraManifestFileCli(arg || undefined);

View File

@@ -0,0 +1,65 @@
#!/usr/bin/env node
/**
* Validate config/universal-resource-activation/policy-profiles.json against
* universal-resource-activation.policy-profile-registry.v1.schema.json
* and ensure manifest policyProfileRefs[] ids exist in the registry.
*
* Usage: from repo root — node scripts/validate/validate-ura-policy-profiles.mjs
*/
import { readFileSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.join(__dirname, '../..');
const registryPath = path.join(projectRoot, 'config', 'universal-resource-activation', 'policy-profiles.json');
const registrySchemaPath = path.join(
projectRoot,
'config',
'universal-resource-activation.policy-profile-registry.v1.schema.json',
);
const manifestPath = path.join(projectRoot, 'config', 'universal-resource-activation', 'manifest.json');
function fail(msg) {
console.error(`[validate-ura-profiles] ${msg}`);
process.exit(1);
}
if (!existsSync(registryPath)) fail(`Missing ${registryPath}`);
if (!existsSync(registrySchemaPath)) fail(`Missing ${registrySchemaPath}`);
const ajv = new Ajv({ allErrors: true, strict: false, validateSchema: false });
addFormats(ajv);
const registrySchema = JSON.parse(readFileSync(registrySchemaPath, 'utf8'));
const validateRegistry = ajv.compile(registrySchema);
const registry = JSON.parse(readFileSync(registryPath, 'utf8'));
if (!validateRegistry(registry)) {
console.error('[validate-ura-profiles] policy-profiles.json failed schema:', validateRegistry.errors);
process.exit(1);
}
const ids = new Set(registry.profiles.map((p) => p.policyProfileId));
console.log(`[validate-ura-profiles] OK: ${ids.size} profile(s) in registry`);
if (existsSync(manifestPath)) {
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
const refs = manifest.policyProfileRefs || [];
for (const r of refs) {
const pid = r.id;
if (!pid || !ids.has(pid)) {
fail(`manifest policyProfileRefs contains unknown or missing id: "${pid}"`);
}
}
for (const res of manifest.resources || []) {
const pid = res.policyProfileId;
if (pid && !ids.has(pid)) {
fail(`resource ${res.resourceId} references unknown policyProfileId: "${pid}"`);
}
}
console.log('[validate-ura-profiles] OK: manifest refs match registry');
}

View File

@@ -188,6 +188,15 @@ else
log_warn "Optional config/universal-resource-activation/policy-profiles.json missing; skipping"
fi
# Optional production gate: URA_STRICT_CLOSURE=1 fails if pilots/TBD/open reconciliation remain
if [[ -f "$PROJECT_ROOT/config/universal-resource-activation/integration/omnl-ledger-mapping.v1.json" ]] && command -v node &>/dev/null && [[ -f "$PROJECT_ROOT/scripts/validate/validate-omnl-ledger-mapping.mjs" ]]; then
log_ok "Found: config/universal-resource-activation/integration/omnl-ledger-mapping.v1.json"
if node "$PROJECT_ROOT/scripts/validate/validate-omnl-ledger-mapping.mjs" "$PROJECT_ROOT/config/universal-resource-activation/integration/omnl-ledger-mapping.v1.json"; then
log_ok "omnl-ledger-mapping.v1.json: JSON Schema OK"
else
log_err "omnl-ledger-mapping.v1.json: validation failed"
ERRORS=$((ERRORS + 1))
fi
fi
if [[ "${URA_STRICT_CLOSURE:-}" == "1" ]] && [[ -f "$PROJECT_ROOT/scripts/ura/validate-manifest-closure.mjs" ]]; then
log_info "URA_STRICT_CLOSURE=1: running URA manifest closure gate…"
if node "$PROJECT_ROOT/scripts/ura/validate-manifest-closure.mjs" --strict; then

View File

@@ -1,6 +1,11 @@
#!/usr/bin/env bash
# Universal resource activation — local smoke: JSON Schema validation (always) +
# optional HTTP GET to Phoenix (when --http or PHOENIX_BASE_URL is set).
# optional HTTP GETs to Phoenix (when --http or PHOENIX_BASE_URL is set):
# 1) GET /api/v1/universal-resource-activation/manifest (expect 200 + .schemaVersion)
# 2) GET /api/v1/universal-resource-activation/policy-profiles (expect 200 + .profiles array)
# 3) GET /api/v1/universal-resource-activation/server-funds-sidecar-probe
# — expect 200 (sidecar ok or probe JSON) or 503 with .configured == false (URL unset)
# — 502 = fail (URL set but sidecar paths not healthy)
#
# Usage (repo root):
# bash scripts/verify/smoke-universal-resource-activation.sh
@@ -61,7 +66,9 @@ fi
log "GET $URL (expect 200, JSON with .schemaVersion)…"
body_file="$(mktemp)"
trap 'rm -f "$body_file"' EXIT
probe_file="$(mktemp)"
profiles_file="$(mktemp)"
trap 'rm -f "$body_file" "$probe_file" "$profiles_file"' EXIT
code=$(curl -sS -o "$body_file" -w '%{http_code}' --connect-timeout 5 --max-time 15 "$URL" || true)
if [[ "$code" != "200" ]]; then
@@ -78,4 +85,42 @@ if ! jq -e '.schemaVersion | type == "string"' "$body_file" &>/dev/null; then
exit 1
fi
log "HTTP OK (.schemaVersion present; HTTP $code)"
PROFILES_URL="${BASE}/api/v1/universal-resource-activation/policy-profiles"
log "GET $PROFILES_URL (expect 200, JSON with .profiles array)…"
prcode=$(curl -sS -o "$profiles_file" -w '%{http_code}' --connect-timeout 5 --max-time 15 "$PROFILES_URL" || true)
if [[ "$prcode" != "200" ]]; then
log_err "policy-profiles HTTP $prcode (expected 200). BASE=$BASE"
exit 1
fi
if ! jq -e '(.profiles | type == "array")' "$profiles_file" &>/dev/null; then
log_err "policy-profiles response missing .profiles array"
cat "$profiles_file" >&2
exit 1
fi
log "policy-profiles HTTP OK"
PROBE_URL="${BASE}/api/v1/universal-resource-activation/server-funds-sidecar-probe"
log "GET $PROBE_URL (expect 200 OK response or 503 with configured not true when URL unset)…"
pcode=$(curl -sS -o "$probe_file" -w '%{http_code}' --connect-timeout 5 --max-time 20 "$PROBE_URL" || true)
if [[ "$pcode" == "200" ]]; then
if ! jq -e 'type == "object"' "$probe_file" &>/dev/null; then
log_err "Probe response is not a JSON object"
exit 1
fi
log "sidecar-probe HTTP 200 (JSON object returned)"
elif [[ "$pcode" == "503" ]]; then
if ! jq -e '.configured == false' "$probe_file" &>/dev/null; then
log_err "Probe expected 503 with .configured==false when SERVER_FUNDS_SIDECAR_URL unset; got: $(head -c 400 "$probe_file")"
exit 1
fi
log "sidecar-probe HTTP 503 (SERVER_FUNDS_SIDECAR_URL not set — expected in dev)"
elif [[ "$pcode" == "502" ]]; then
log_err "sidecar-probe HTTP 502 — SERVER_FUNDS_SIDECAR_URL is set but sidecar health paths failed. Fix env or sidecar. Body: $(head -c 400 "$probe_file")"
exit 1
else
log_err "sidecar-probe HTTP $pcode (expected 200, 503, or 502). Body: $(head -c 400 "$probe_file")"
exit 1
fi
exit 0