Add Strain Hospice for graceful low-win strain retirement.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Archive failed epidemiology strains to museum hospice with SQLite persistence, operator/AI/court triggers, breeding and graft guards, topology museum nodes, and Seer plus oath ledger accountability.
This commit is contained in:
AetherForge
2026-06-07 09:26:39 -07:00
parent 894b7a50ae
commit d605ef4adb
18 changed files with 701 additions and 18 deletions

View File

@@ -2,6 +2,8 @@
* Onion timeline fork/merge helpers for Path Tracer UI + Seer/AI context.
*/
import { spreadStrainFromJoinLane } from './fleetTopologyEpidemiology';
export type TimelineBranchStatus =
| 'canonical'
| 'running'
@@ -89,8 +91,28 @@ export function ghostBranchesByHop(branches: PathTraceTimelineBranch[]): Map<num
return map;
}
export function pickMergeCandidate(branches: PathTraceTimelineBranch[]): PathTraceTimelineBranch | null {
const ghosts = branches.filter((b) => b.is_ghost);
function branchPrimaryLane(branch: PathTraceTimelineBranch): string {
return branch.spread_lanes?.[0]?.trim() ?? '';
}
/** Spread strain from join lane — mirrors Go SpreadStrainFromJoinLane for hospice guards. */
export function spreadStrainFromPersonaLane(lane: string): string {
if (!lane) return '';
return spreadStrainFromJoinLane(lane).toLowerCase();
}
export function pickMergeCandidate(
branches: PathTraceTimelineBranch[],
hospiceStrains?: Set<string>,
): PathTraceTimelineBranch | null {
const hospice = hospiceStrains ?? new Set<string>();
const eligible = (b: PathTraceTimelineBranch) => {
const lane = branchPrimaryLane(b);
if (!lane || hospice.size === 0) return true;
const strain = spreadStrainFromPersonaLane(lane);
return strain === '' || !hospice.has(strain);
};
const ghosts = branches.filter((b) => b.is_ghost && eligible(b));
const won = ghosts.find((b) => b.status === 'won' || b.mining_linked);
if (won) return won;
const running = ghosts.find((b) => b.status === 'running');