Two dead CAMEO event-count signals retired in favour of one signal counting Haiku-classified disruption articles per locode. Part 13 of the stack, and the only PR in the chain that moves forecast numbers.
Every other PR in the stack #88 through #100 is structural. This one is the single change that alters the numbers a forecast produces: the news evidence channel stops counting CAMEO events and starts counting disruption articles classified by Haiku, attributed per locode over a trailing 7-day window.
Both signals were producing no usable evidence. They are removed from the signal set rather than left inert, so nothing downstream can read a stale channel.
Counts Haiku-classified disruption articles per locode over the trailing 7 days, then scores that count as a z-score against its rolling baseline.
The new signal joins the news_port_state family alongside the stronger port state peer. When both fire, only the strongest member reaches the posterior; the loser is suppressed and the suppression is recorded.
A publication-hardening pass added eleven commits on top of the repoint itself. Each one exists to make the change safe to publish against a live production database rather than to change what the model computes.
Five stages, left to right within each lane and top to bottom between them. Dashed blue edges are reads from a store; solid green edges carry a derived value forward; the dashed red edge is the correlated-family suppression. Hover any node to isolate the edges it touches and reveal their labels.
threshold_z 2.0, contributes LR 2.5LR 4.0Changing the signal set changes the shape of the observation the hidden Markov model consumes. The vector narrows from five dimensions to three, and the order of those three is canonical: inference reads positionally, so the order is part of the contract rather than a convention.
Inference runs on NumPy alone. No sampler, no probabilistic-programming runtime, and no model fitting inside the scoring loop.
Exactly one hmm_config document in forecasting.mappings holds the contract. It is strict: shapes and canonical order must match or the model does not load.
That document is replaced only through the cutover CLI, which requires the exact expected preimage and moves in one direction. There is no in-place edit and no reverse step.
Publishing the repoint against a live database is an ordered ladder of thirteen steps. The order is load-bearing: every step either establishes a guarantee the next step depends on, or proves that a guarantee already established still holds.
Record the current scheduling configuration before touching anything, so the end state can be compared against a known starting point.
Take the running application down so that nothing is scoring while the underlying contract is being changed.
The gate depends on a uniqueness guarantee. The index is installed and then verified, not assumed.
The gate is created and switched on. From this point scoring is fail-closed: it runs only if the gate explicitly permits it.
The new code is deployed with scheduled execution disabled, so deployment itself cannot start a scoring run.
Blocking is demonstrated from both surfaces: the CLI refuses to score, and the API answers with 503.
Every index the new query patterns rely on is confirmed present before any of them are exercised.
Watches are brought in line with the new signal set, so nothing is still watching a signal that no longer exists.
Schema version records are published under the write-once rules detailed in section E: insert when absent, no-op on exact match, abort on drift.
The single hmm_config document is replaced through the forward-only, exact-preimage CLI. Bounded means it changes that one document and nothing else.
The deployed build is exercised without writing. Authorization for the canary is revocable and bound to both the database identity and the cutover ID, so it cannot be replayed elsewhere or later.
Normal deployment configuration is restored first, with the gate still closed. Restoring and unblocking are two separate steps, never one.
Only now is scoring allowed to resume. The gate is the last thing to move, not the first.
There is no rollback path down the ladder. If any step fails, the scoring gate stays active and schedules stay off - the system holds in the blocked state rather than resuming with a half-applied contract.
Schema version records are published, never updated. The publisher is defined by what it does in each of four situations, and two of those four are refusals. Drift is detected before anything is written, so a mismatched record can never be silently overwritten by a deploy.
| Situation at publish time | Publisher action | Outcome |
|---|---|---|
| No record exists for this (collection, version) | insert | The record is created. This is the only path that writes. |
| A record exists and matches exactly | no-op | Nothing is written. Republishing the same contract is safe and repeatable. |
| A record exists and differs (drift) | fail | Publication fails before any write. The stored contract is never mutated to match the code. |
| Duplicate-key race: a concurrent writer won the insert | reread and compare | The winning record is reread and must match exactly; anything else fails. The race cannot smuggle in a different contract. |
The v1 record is restored rather than dropped, so the historical shape stays describable after the repoint.
The v2 record documents the retirement of v1 and adds the flat Bayesian audit fields the correlated-family guard writes.
Sixteen review outcomes across the eight-role team protocol and four independent lanes, plus the test evidence. Filter by outcome class, then click any card to expand its lens, what was examined, and the resulting position.
The repoint carries one behavioural change and a hardening pass built to publish it safely. Both remaining defects were corrected at the final SHA rather than deferred.