Blue Fire Command — Phase 2A.25

Regression Guard Integration Review

REVIEW ONLY — NOT FOR EMERGENCY USE

This page contains no JavaScript, does not read or write browser storage, and cannot modify any incident record. It is a candidate source patch for review, not a deployed fix.

Target: the original development-source persistIncident() function. Existing incident identity checks must remain intact.

Proposed safety check

Before overwriting cfc_active, reject writes that remove a populated address, shrink the legacy event timeline, rewrite existing historical events, or change incident identity.

/* BFC-010 Phase 2A.25 — CANDIDATE ONLY. NOT DEPLOYED.
   Review and test in a completely isolated copy before any development integration.
   Insert this guard immediately before the existing localStorage.setItem('cfc_active', ...)
   in persistIncident(), AFTER existing incident-identity checks and state construction.
   The following is an integration fragment, not a standalone drop-in script.
*/
function bfc010CandidateRegressionCheck(previous, state) {
  if (!previous) return {ok:true,reason:'NO_PREVIOUS_RECORD'};
  if (previous.incidentId !== state.incidentId)
    return {ok:false,reason:'IDENTITY_MISMATCH'};
  const priorAddress = typeof previous.address === 'string' ? previous.address.trim() : '';
  const nextAddress = typeof state.address === 'string' ? state.address.trim() : '';
  if (priorAddress && !nextAddress)
    return {ok:false,reason:'ADDRESS_REGRESSION'};
  if (Array.isArray(previous.events)) {
    if (!Array.isArray(state.events) || state.events.length < previous.events.length)
      return {ok:false,reason:'EVENT_COUNT_REGRESSION'};
    // Do not accept same-count replacement of historical legacy timeline entries.
    // Legacy log prepends, so the old timeline must remain as an ordered suffix.
    const offset = state.events.length - previous.events.length;
    for (let i=0;i<previous.events.length;i++) {
      if (JSON.stringify(state.events[offset+i]) !== JSON.stringify(previous.events[i]))
        return {ok:false,reason:'EVENT_HISTORY_REWRITE'};
    }
  }
  return {ok:true,reason:'NO_REGRESSION_DETECTED'};
}
/* Inside persistIncident(), after `const state={...};` and before setItem:
 const check=bfc010CandidateRegressionCheck(previous,state);
 if (!check.ok) {
   console.error('BFC-010 Phase 2A.25: active write blocked',check.reason);
   // Test-only: no silent fallback and no attempt to rewrite prior evidence.
   return false;
 }
 // Existing setItem and return true remain unchanged.
*/

Validation gate

Phase 2A.24 reproduced the original overwrite and passed isolated tests of the candidate address/count guard. This more conservative candidate additionally checks historical event sequence. It has NOT yet been tested in the full app or through a browser reload.

HOLD — no operational testing, no development deployment, no production deployment.