- Documentation
- /
- Blast
- /
Application Overview
What the Blast Planning and Explosives Management app models, and the ideas behind it
Core Operating Chain
BlastRequest → Blast (why we are blasting)
Blast → BlastDesign (self-superseding) → BlastDesignApproval
Blast → BlastRiskAssessment → BlastHazard (initial → residual rating)
Blast → BlastBoundary (exclusion / vehicle / advisory)
MineSite → SensitiveReceiver → BlastReceiverAssessment
(predicted vibration + airblast)
Blast → BlastHole → DrillActivity (what was actually drilled)
→ HoleSurvey (deviation accepted?)
→ HoleConditionInspection (suitable_for_charging — the gate)
ExplosiveProduct → ExplosiveBatch (the custody unit)
ExplosivesMagazine → MagazineInspection
→ ExplosiveStockLocation → ExplosiveStockBalance
ExplosiveBatch → ExplosiveStockTransaction (RECEIPT · ISSUE · CONSUMPTION ·
RETURN · QUARANTINE · STOCKTAKE)
ExplosivesTransportMovement → TransportMovementItem (magazine → bench, sealed)
Blast → ChargingPlan → HoleChargePlan (planned, per hole and deck)
→ ChargingSession → HoleChargeActual (actual product, batch, quantity)
→ ChargingQualityCheck (stemming, charge weight, primer)
Blast → InitiationPlan → TieInConnection (continuity verified)
Blast → BlastNotification (neighbours, pipeline, regulator)
→ ClearancePlan → GuardPost / AreaClearance (every post must confirm clear)
→ WeatherObservation (suitable_to_fire)
→ PreFireChecklist → BlastFiring (15 checks, then authorisation)
Blast → PostBlastInspection → ReentryAuthorisation (blocked while a misfire is open)
→ BlastMonitoringRecord (via BlastMonitoringInstrument, per receiver)
→ FlyrockObservation / FumeObservation
→ FragmentationAssessment / MuckpileAssessment
→ Misfire → MisfireTreatment (isolate → assess → treat → verify)
→ BlastReconciliation (holes, explosives, tonnage)
→ BlastCostRecord
BlastIncident → Investigation → InvestigationFinding → CorrectiveAction
MineSite → Audit → AuditFinding (findings link to actions)
ExplosivesManagementPlan → PlanRequirementLink → Requirement → SourceDocument
Person → PersonAuthorisation (licence, expiry, verification)
Key Concepts
A hole that fails its condition inspection cannot be charged.
HoleConditionInspection.suitable_for_charging is a required boolean, and it
is the gate the pack's RejectedHoleCannotBeCharged rule is written against. In
the demo, hole NP480-007 collapsed at 4.2 m against a planned 10.8 m with 1.8 m
of standing water. It is set REDRILL_REQUIRED, it is absent from the charge
plan, it has no HoleChargeActual row at all, and the tie-in sequence skips
it. Twelve holes were drilled; eleven were charged. That difference propagates
all the way into the reconciliation.
Explosives are traced by batch, not by quantity. Every movement is an
ExplosiveStockTransaction against an ExplosiveBatch — issue to the mobile
processing unit, consumption into holes, return of the unused product,
quarantine of a water-damaged batch. HoleChargeActual records the batch used
for the main charge, the booster and the detonator as three separate columns, so
a suspect batch can be traced to the exact holes it went into. This is what makes
the reconciliation meaningful rather than arithmetic.
The pre-fire checklist is a gate, not a form. PreFireChecklist carries
fifteen required booleans — design approved, drilling accepted, charging
complete, tie-in verified, explosives reconciled to field, notifications
complete, guards confirmed, exclusion zone clear, weather acceptable,
communications operational, firing system test passed, misfire procedure
available, emergency response available, and more. all_checks_passed is a
derived field, and authorised_to_fire_by_person_id is separate from
completed_by_person_id: the person who completes the checks is not the person
who authorises the fire.
Every guard post must confirm clear — and one nearly didn't. The pack's
ClearanceGate and AbortOnLostCommunication rules turn on
GuardPost.status == CONFIRMED_CLEAR for every post. The demo's GP-03 (the
public road boundary) failed its initial radio check at 13:38; firing was held
until the guard re-established communications on the backup channel and confirmed
clear at 13:52. The event is visible in the guard post record rather than
smoothed away, because a clearance that always succeeds tells you nothing.
A suspected misfire blocks re-entry. PostBlastInspection.area_safe_for_reentry
is required, and when the first inspection found an intact collar and undisturbed
stemming at NP480-012 it was recorded false with the exclusion maintained. The
Misfire then runs its own lifecycle — SUSPECTED → AREA_ISOLATED → ASSESSED →
TREATMENT_APPROVED → RESOLVED → VERIFIED → CLOSED — through four
MisfireTreatment steps: isolate and wait, task risk assessment, wash out and
recover, then independent verification by a different person. Only after that
does a second inspection record area_safe_for_reentry = true and a
ReentryAuthorisation exist. The two inspections, in order, are the record.
Approval roles are deliberately separable. The pack ships a
segregation-of-duties matrix — approve a design ≠ prepare it, approve a stock
adjustment ≠ create it, verify a misfire resolution ≠ perform the treatment — and
the schema gives each of those its own column so the separation is checkable. The
demo honours all three: Okonkwo prepared the design and Hale/Dube/Pearce approved
it; McLeod washed out the misfired hole and Reyes verified it. tab_config.yaml
labels every one of these roles so a Person page reads "Designs Prepared" and
"Design Approvals Given" as different facts.
The blast has not closed, and that is the point. BlastReconciliation
records a 3.5 kg unexplained variance between explosives issued (4200 kg),
charged (4028.5 kg) and returned (168 kg) — above the site's 2 kg tolerance. So
stock_reconciled is false, the reconciliation sits at REVIEW with no
approver, corrective action BL-ACT-2026-00019 is open, and Blast.blast_stage
remains RECONCILIATION with closed_at null. That is the pack's
ExplosivesVariance and BlastClosureGate rules made visible as data.
The application is not the design tool. The boundary carried over from the pack, and worth repeating: this is a configurable operational record system, not a blast-design calculator, an electronic initiation controller, an explosives manufacturing control system or a monitoring historian. Specialist design, firing and high-frequency monitoring systems remain authoritative for their technical functions; what is stored here is the governed summary, the file reference, the approval, the decision and the outcome.
What Is Phase 2
The proforma pack ships seven workflows (BlastDesignAndApproval,
DrillValidation, ExplosivesIssueAndCharging, ClearanceAndFiring,
PostBlastAndReentry, MisfireResponse, BlastReconciliationAndClose), a
sixteen-state BlastStage lifecycle with explicit transitions, thirteen business
rules (CurrentAuthorisationRequired, ApprovedDesignRequired,
RejectedHoleCannotBeCharged, StockCannotGoNegative,
BatchTraceabilityRequired, ChargingDeviationControl, ClearanceGate,
AbortOnLostCommunication, MisfireIsolation, MonitoringExceedance,
FlyrockOutsideZone, ExplosivesVariance, BlastClosureGate), the
segregation-of-duties matrix, numbering masks (BL-{YYYY}-{SEQ:05} and friends),
an offline field-capture profile with immutable-after-sync models, and five
dashboards and seven reports. None of that is enforced by the schema — the
demo data is consistent with those rules rather than validated against them,
and the reference numbers follow the masks by hand. Derived fields
(quantity_available, discrepancy, all_checks_passed, exceeded,
unexplained_variance_kg, actual_powder_factor) are stored columns populated
by the seed, not computed. See the header of apps/blast/schema/blast.dsl for the
full translation record.