Coastal Shipping 12 — Customs & Border Clearance Interface (coast_12_customs)

Is customs clearance required for this cargo — and, where it is, is there a current, authorised clearance for exactly this scope and manifest revision with no hold standing? — customs applicability, broker mandates, declarations, official decisions, regulatory holds and the current clearance position.

Its central question:

May this consignment, this cargo line and container, at this manifest revision, be commercially released right now as far as customs is concerned — and if not, why not?

coast_12_customs is application SHP-12 of the Coastal Shipping series (coast_NN_<name>, numbered by the pack catalogue; each able to run stand-alone or as a member of a network). It shares no tables and no foreign keys with its siblings (for example coast_10_release, which asks it for a live clearance check and consumes its clearance and hold events, or coast_03_tracking, which applies its own scoped hold) — they link by canonical_ref strings and by messages. All data is fictional.

SIMULATION ONLY. The customs authority adapter (the pack names ASYCUDA World as a category of target) is a simulation: this application holds no real wire format, endpoint, credential, tariff or legal claim. A simulated transmission is marked SIMULATED_SENT and a simulated official result is marked mode SIMULATION; a simulated clearance, hold or lift never authorises a live release (release_authorised is false unless the assessment is LIVE). Activating a live adapter needs current authority and broker specifications and approval (the pack's README step 9).

The spine

ClearanceProfile → CustomsDeclaration → DeclarationItem / CustomsDocument / CustomsTransmission → CustomsDecision → RegulatoryHold → ClearanceAssessment (current position) → CustomsClearanceCheck (the answer to SHP-10), with BrokerMandate, DeclarationAmendment, CustomsException and CustomsAudit around it.

The documents

Page What's in it
00 — Overview What the app is, applicability, classification, acceptance vs clearance, simulation, the rules, the 15 models, the demo scenario
01 — Quick Reference Menu map, every model, status vocabularies, the messages, how to run, seed and regenerate
02 — System Diagram The data model as diagrams (+ interactive viewer) and how the app links to its siblings

Status

Built (handlers and workflow, tested): explicit applicability (import / export / transit / COASTAL; a domestic shipment needs no declaration and is not presumed cleared — it needs an evidence-backed, independently approved NOT_REQUIRED assessment); HS classification kept apart from the commercial commodity class; declaration validate / approve / submit / accept / reject / clear / hold / reinstate / supersede with independent approval, mandate and profile checks, an immutable submitted revision and item snapshot, and amendments as new linked versions; official decisions that are verified by someone other than the recorder or QUARANTINED when unmatched, unauthenticated or mismatched; regulatory holds placed from verified results and lifted ONLY by the matching verified lift; versioned immutable clearance assessments (a hold, a newer manifest revision or elapsed validity turn them HELD or STALE); the live check customs.check_clearance that SHP-10 sends (never a silent positive; one answer per command key; published as customs.clearance_checked); the scheduled sweep; the simulation test harness customs.simulate_decision.

Published: customs.clearance_changed, customs.hold_changed, customs.clearance_checked, customs.exception_raised / _resolved. Consumed: manifest.effective_cargo, release.document_issued, assurance.action_requested. Accepted commands: customs.check_clearance (coast_10_release, orchestrator), customs.simulate_decision and customs.sweep_expired (orchestrator).

Not built: a live adapter; the authority's own field validation and tariff checks (the HS code is checked only for form and evidence); the late-hold-after-gate comparison with the yard's gate fact (coast_10_release owns CUSTOMS_RELEASE_CONFLICT); the network must register this member, wire the three scheduled/consumed routes and bind SHP-10, SHP-03 and SHP-16 consumers. The rules are in integration/rules.py and integration/handlers.py, the arithmetic in integration/calc.py, with their tests under server/tests/integration_apps/test_coast_12_customs_*.py.

Translation decisions (pack models.dsl, business_rules.yaml, workflows.yaml, views.yaml to native DSL)

  • As the other coastal apps: fleet-unique model names, canonical_ref on every model, cid on the four network entities (assessment, hold, clearance check, exception), name on every foreign-key target, cross-app references as strings (*_canonical_ref, *_ref, *_cid), Decimal(p,s), upper-case [enum:] lists, Index lines dropped.
  • S832_Audit → CustomsAudit; S835_ExternalSnapshot → CustomsExternalSnapshot; S833_OutboxEvent and S834_InboxMessage are dropped (the integration runtime provides them). All other model names are the pack's without the Snnn_ prefix. code → authority_code / profile_code; version → version_no.
  • Added beyond the pack: CustomsException (the app's own control exception; the pack's generic shipping.control.exception_detected.v1 becomes customs.exception_raised) and CustomsClearanceCheck (the append-only answer to a live check: this runtime does not route a command's answer back to the sender, so SHP-10 learns it from customs.clearance_checked, correlated by check_idempotency_key). Fields: ClearanceProfile.declaration_required / notes; mode (SIMULATION / LIVE) on profile, transmission, decision, hold and assessment; the verification, quarantine, valid_until, hold_type, lifts_hold_ref and detail fields of a decision; scope_json, version_no, requirement, mode, assessed_by, approved_by, reason on the assessment; hold_no, version_no and the lift decision on the hold.
  • Deviation: CustomsDecision.declaration_id is optional (the pack makes it required): an unmatched or unauthenticated result must be stored and QUARANTINED with the declaration it claimed rather than matched by guess, and a hold, revocation or lift may arrive for a consignment with no declaration (a domestic cargo).
  • Pack event and command names are mapped as shipping.customs.clearance_changed.v1 → customs.clearance_changed, shipping.customs.hold_changed.v1 → customs.hold_changed, check_customs_clearance → customs.check_clearance (the runtime allows one dot in a message type, see docs/coastal_shipping/NETWORK.md). The pack's idempotency_key field is the envelope's own.
  • Pack hold and decision vocabularies are open strings in the pack; the lists in the DSL are this application's. The pack's authorised_channel, authorised_broker and similar guard names are implemented as the checks named in rules.py.
  • The ASYCUDA / broker transmission is SIMULATION only: CustomsTransmission records SIMULATED_SENT (or QUEUED for a LIVE profile, which has no adapter here).

Prototype system; draft. All names and amounts in the demo data are fictional. Nothing here is a customs declaration, a tariff classification or legal advice.