Phase 23 — contract terms + staffer identity + competence-weighted retrieval

Matrix-index the "who handled this" dimension so top staffers become
the training signal and juniors inherit their playbooks automatically
via the boost pipeline. Auto-discovered indicators emerge from
comparing trajectories across staffers on similar contracts — that was
always the architectural point; this wires the last piece.

ContractTerms:
- deadline, budget_total_usd, budget_per_hour_max, local_bonus_per_hour,
  local_bonus_radius_mi, fill_requirement ("paramount" | "preferred")
- Attached to ScenarioSpec, propagated into T3 checkpoint + cloud
  rescue prompts so cloud reasons about trade-offs (pivot within bonus
  radius first; respect per-hour cap; split across cities when
  fill_requirement=paramount).

Staffer:
- {id, name, tenure_months, role: senior|mid|junior|trainee}
- On ScenarioSpec; logged at scenario start; attached to KB outcome
- Recomputed StafferStats written to data/_kb/staffers.jsonl after
  every run: total_runs, fill_rate, avg_turns, avg_citations,
  rescue_rate, competence_score.
- Competence formula: 0.45*fill_rate + 0.20*turn_efficiency +
  0.20*citation_density + 0.15*rescue_rate. Normalized to 0..1.

findNeighbors now returns weighted_score = cosine × best_staffer_competence
(floored at 0.3 so high-similarity low-competence neighbors still
surface). pathway_recommender prompt shows the top staffer's identity
so cloud knows WHOSE playbook it's synthesizing from.

Demo infrastructure:
- tests/multi-agent/gen_staffer_demo.ts: 4 personas (Maria senior,
  James mid, Sam junior, Alex trainee) × 3 contracts (Nashville Welder,
  Joliet Warehouse, Indianapolis Assembly). 12 scenarios total.
- scripts/run_staffer_demo.sh: runs the 12 sequentially with
  LH_OVERVIEW_CLOUD=1. Post-run calls kb_staffer_report.py.
- scripts/kb_staffer_report.py: leaderboard + cross-staffer worker
  overlap (names endorsed by ≥2 staffers → auto-discovered high-value
  workers). Top vs bottom differential.

gen_scenarios.ts (Phase 22 generator) also now emits contract terms
on 70% of generated specs — future KB batches populate with realistic
constraint patterns instead of bare role+city+count.

Stress scenario from item A intentionally NOT the production test.
Real staffing has constraints; Nashville contract + staffer demo is
the honest test of whether the architecture produces measurable
differential between coordinator skill levels.

Demo batch launched — 12 runs × ~3min each ≈ 40min unattended. Report
emitted after batch.
This commit is contained in:
root 2026-04-20 22:16:09 -05:00
parent a7fc8e2256
commit 6b71c8e9b2
41 changed files with 2316 additions and 34 deletions

108
scripts/kb_staffer_report.py Executable file
View File

@ -0,0 +1,108 @@
#!/usr/bin/env python3
"""Phase 23 staffer leaderboard + cross-staffer pattern finder.
Reads data/_kb/staffers.jsonl + outcomes.jsonl + signatures.jsonl and
emits:
- Leaderboard sorted by competence_score
- Per-staffer breakdown (fill rate, turns, citations, rescue rate)
- Cross-staffer common workers: names endorsed by multiple top
staffers on similar signatures candidates for "auto-discovered
high-value worker" labels.
Run after scripts/run_staffer_demo.sh completes.
"""
import json
import os
from collections import defaultdict, Counter
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
KB = ROOT / "data" / "_kb"
PLAYBOOKS = ROOT / "tests" / "multi-agent" / "playbooks"
def load_jsonl(p):
if not p.exists():
return []
out = []
for line in p.read_text().splitlines():
if line.strip():
try:
out.append(json.loads(line))
except json.JSONDecodeError:
pass
return out
def main():
staffers = load_jsonl(KB / "staffers.jsonl")
outcomes = load_jsonl(KB / "outcomes.jsonl")
if not staffers:
print("(no staffer stats yet — run scripts/run_staffer_demo.sh first)")
return
staffers.sort(key=lambda s: -s["competence_score"])
print("=== STAFFER LEADERBOARD ===")
print(f"{'rank':4s} {'id':7s} {'name':16s} {'role':8s} {'mo':>4s} {'runs':>4s} {'fill':>6s} {'turns':>6s} {'cites':>6s} {'rescue':>7s} {'score':>6s}")
print("-" * 100)
for i, s in enumerate(staffers):
rank_mark = "" if i == 0 else " "
print(f"{rank_mark}{i+1:3d} {s['id']:7s} {s['name']:16s} {s['role']:8s} {s['tenure_months']:>4d} {s['total_runs']:>4d} {s['fill_rate']*100:>5.1f}% {s['avg_turns_per_event']:>6.1f} {s['avg_citations_per_run']:>6.2f} {s['rescue_rate']*100:>6.1f}% {s['competence_score']:>6.3f}")
print()
# Cross-staffer pattern — workers endorsed on the same sig_hash
# across multiple staffers. Auto-discovered "reliable performers".
print("=== CROSS-STAFFER WORKER OVERLAP ===")
print("(workers endorsed on same sig_hash by ≥2 staffers)")
worker_touches = defaultdict(lambda: {"staffers": set(), "sigs": set(), "endorsements": 0})
for o in outcomes:
run_dir = PLAYBOOKS / o["run_id"]
results_file = run_dir / "results.json"
if not results_file.exists():
continue
try:
results = json.loads(results_file.read_text())
except Exception:
continue
staffer_id = o.get("staffer", {}).get("id")
if not staffer_id:
continue
for r in results:
if not r.get("ok"):
continue
for f in r.get("fills", []):
name = f.get("name")
if not name or name.startswith("Candidate "):
continue
key = (name, r["event"]["role"], r["event"]["city"], r["event"]["state"])
worker_touches[key]["staffers"].add(staffer_id)
worker_touches[key]["sigs"].add(o["sig_hash"])
worker_touches[key]["endorsements"] += 1
shared = sorted(
[(k, v) for k, v in worker_touches.items() if len(v["staffers"]) >= 2],
key=lambda x: -x[1]["endorsements"],
)
if shared:
for (name, role, city, state), v in shared[:15]:
print(f" {name:25s} {role:22s} {city:15s} {state}: {v['endorsements']} endorsements across {len(v['staffers'])} staffers")
else:
print(" (none yet — needs ≥2 staffers on overlapping scenarios)")
print()
# Competence differential — how much does top vs bottom differ?
if len(staffers) >= 2:
top = staffers[0]
bot = staffers[-1]
print(f"=== TOP vs BOTTOM DIFFERENTIAL ===")
print(f"{top['name']} (top) vs {bot['name']} (bottom):")
print(f" fill rate: {top['fill_rate']*100:.1f}% vs {bot['fill_rate']*100:.1f}% (Δ {(top['fill_rate']-bot['fill_rate'])*100:+.1f}pt)")
print(f" avg turns: {top['avg_turns_per_event']:.1f} vs {bot['avg_turns_per_event']:.1f}{top['avg_turns_per_event']-bot['avg_turns_per_event']:+.1f})")
print(f" avg citations: {top['avg_citations_per_run']:.2f} vs {bot['avg_citations_per_run']:.2f}{top['avg_citations_per_run']-bot['avg_citations_per_run']:+.2f})")
print(f" rescue rate: {top['rescue_rate']*100:.1f}% vs {bot['rescue_rate']*100:.1f}%")
print(f" competence: {top['competence_score']:.3f} vs {bot['competence_score']:.3f}")
if __name__ == "__main__":
main()

46
scripts/run_staffer_demo.sh Executable file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Run the 12 staffer-demo scenarios (4 personas × 3 contracts) with
# cloud T3 enabled. After each run, KB indexes the outcome and
# recomputes that staffer's competence_score. By the end, the top
# staffer's playbooks will be surfacing first in neighbor retrieval.
set -e
cd "$(dirname "$0")/.."
export OLLAMA_CLOUD_KEY="$(python3 -c "import json; print(json.load(open('/root/llm_team_config.json'))['providers']['ollama_cloud']['api_key'])" 2>/dev/null || echo '')"
MANIFEST="tests/multi-agent/scenarios/staffer_demo/manifest.json"
if [ ! -f "$MANIFEST" ]; then
echo "✗ no manifest — run: bun tests/multi-agent/gen_staffer_demo.ts"
exit 1
fi
START_TS=$(date -Iseconds)
LOG_DIR="/tmp/lakehouse_staffer_demo_$(date +%s)"
mkdir -p "$LOG_DIR"
echo "▶ Staffer demo start: $START_TS, logs → $LOG_DIR"
python3 -c "
import json
m = json.load(open('$MANIFEST'))
for s in m['scenarios']:
print(s['file'], '|', s['staffer'], '|', s['contract'])
" | while IFS='|' read -r SCEN STAFFER CONTRACT; do
SCEN=$(echo "$SCEN" | xargs)
STAFFER=$(echo "$STAFFER" | xargs)
CONTRACT=$(echo "$CONTRACT" | xargs)
SPEC="tests/multi-agent/scenarios/staffer_demo/$SCEN"
BASE=$(basename "$SPEC" .json)
LOG="$LOG_DIR/${BASE}.log"
echo "$STAFFER × $CONTRACT"
LH_OVERVIEW_CLOUD=1 bun tests/multi-agent/scenario.ts "$SPEC" > "$LOG" 2>&1 || true
OK=$(grep -oP '\d+/\d+ events succeeded' "$LOG" | tail -1 || echo "no-result")
RESCUES=$(grep -c "cloud rescue requested" "$LOG" || true)
RESCUE_OK=$(grep -c "retry outcome: ✓" "$LOG" || true)
SIG=$(grep -oP 'KB indexed: sig=\K[a-f0-9]+' "$LOG" | tail -1 || echo "-")
echo "$OK; rescues=$RESCUES (${RESCUE_OK} succeeded); sig=$SIG"
done
echo "▶ Staffer demo done: $(date -Iseconds)"
echo "▶ Staffer competence leaderboard:"
python3 scripts/kb_staffer_report.py 2>/dev/null || echo "(run scripts/kb_staffer_report.py after batch completes)"

View File

@ -147,7 +147,30 @@ function genSpec(rng: () => number, id: number): any {
if (events.length > 0) e.replaces_event = events[0].at;
events.push(e);
}
return { client, date, events };
// Contract terms — most real staffing contracts have these. 70% of
// generated specs carry them so KB + T3 learn to reason about budget
// and radius trade-offs, not just geography. Distributions are
// deliberately varied: 2 week to 45 day deadlines, $22-$38/hr caps,
// 25-150mi local radii.
const contract = rng() > 0.3 ? (() => {
const deadlineDays = 10 + Math.floor(rng() * 35);
const deadlineDate = new Date(today.getTime() + (id + deadlineDays) * 86400000)
.toISOString().split("T")[0];
const budgetPerHour = 22 + Math.floor(rng() * 17);
const bonusRadius = 25 + Math.floor(rng() * 125);
const bonusPerHour = 2 + Math.floor(rng() * 5);
const fill: "paramount" | "preferred" = rng() > 0.4 ? "paramount" : "preferred";
return {
deadline: deadlineDate,
budget_per_hour_max: budgetPerHour,
local_bonus_per_hour: bonusPerHour,
local_bonus_radius_mi: bonusRadius,
fill_requirement: fill,
};
})() : undefined;
return { client, date, events, ...(contract ? { contract } : {}) };
}
async function main() {

View File

@ -0,0 +1,120 @@
// Phase 23 demo — 4 staffer personas × 3 contract scenarios each.
// Same contracts run against different staffers to measure competence
// differential. After the batch, findNeighbors should rank top-staffer
// playbooks above junior-staffer playbooks for similar scenarios.
//
// Output: 12 spec files under tests/multi-agent/scenarios/staffer_demo/
import { mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
const STAFFERS = [
{ id: "S-001", name: "Maria Chen", tenure_months: 48, role: "senior" as const },
{ id: "S-002", name: "James Park", tenure_months: 14, role: "mid" as const },
{ id: "S-003", name: "Sam Torres", tenure_months: 4, role: "junior" as const },
{ id: "S-004", name: "Alex Rivera", tenure_months: 1, role: "trainee" as const },
];
// Three contract shapes — one downtown assembly, one warehouse ramp,
// one emergency recovery. Different cities to vary the sig_hash.
const CONTRACTS = [
{
tag: "nashville_downtown",
client: "Riverline Logistics — Nashville Downtown Build-Out",
city: "Nashville", state: "TN",
contract: {
deadline: "2026-05-19",
budget_total_usd: 180000,
budget_per_hour_max: 32,
local_bonus_per_hour: 4,
local_bonus_radius_mi: 75,
fill_requirement: "paramount" as const,
},
events: [
{ kind: "baseline_fill", at: "07:00", role: "Welder", count: 4 },
{ kind: "expansion", at: "08:30", role: "Packaging Operator", count: 6 },
{ kind: "baseline_fill", at: "09:00", role: "Shipping Clerk", count: 2 },
{ kind: "emergency", at: "13:00", role: "Welder", count: 2, deadline: "15:00" },
{ kind: "misplacement", at: "15:30", role: "Packaging Operator", count: 1, replaces_event: "08:30" },
],
},
{
tag: "joliet_warehouse",
client: "Midway Distribution — Joliet DC Ramp",
city: "Joliet", state: "IL",
contract: {
deadline: "2026-05-12",
budget_total_usd: 120000,
budget_per_hour_max: 28,
local_bonus_per_hour: 3,
local_bonus_radius_mi: 50,
fill_requirement: "preferred" as const,
},
events: [
{ kind: "baseline_fill", at: "07:00", role: "Warehouse Associate", count: 5 },
{ kind: "recurring", at: "10:00", role: "Forklift Operator", count: 3 },
{ kind: "expansion", at: "12:30", role: "Picker", count: 4 },
{ kind: "misplacement", at: "15:00", role: "Forklift Operator", count: 1, replaces_event: "10:00" },
],
},
{
tag: "indianapolis_assembly",
client: "Pioneer Assembly — Indianapolis Plant Expansion",
city: "Indianapolis", state: "IN",
contract: {
deadline: "2026-05-26",
budget_total_usd: 220000,
budget_per_hour_max: 30,
local_bonus_per_hour: 5,
local_bonus_radius_mi: 60,
fill_requirement: "paramount" as const,
},
events: [
{ kind: "baseline_fill", at: "07:30", role: "Assembler", count: 6 },
{ kind: "recurring", at: "09:30", role: "Quality Tech", count: 2 },
{ kind: "expansion", at: "11:00", role: "Machine Operator", count: 5 },
{ kind: "emergency", at: "14:00", role: "Machine Operator", count: 3, deadline: "16:00" },
{ kind: "misplacement", at: "16:00", role: "Assembler", count: 1, replaces_event: "07:30" },
],
},
];
async function main() {
const outDir = "tests/multi-agent/scenarios/staffer_demo";
await mkdir(outDir, { recursive: true });
const manifest: Array<{ file: string; staffer: string; contract: string; client: string }> = [];
let day = 0;
for (const staffer of STAFFERS) {
for (const ct of CONTRACTS) {
day += 1;
const date = new Date(Date.now() + day * 86400000).toISOString().split("T")[0];
const spec = {
client: ct.client,
date,
contract: ct.contract,
staffer,
events: ct.events.map(e => ({
...e,
city: ct.city,
state: ct.state,
shift_start: `${e.at} ${e.at.startsWith("0") ? "AM" : "PM"}`,
scenario_note: `Staffed by ${staffer.name} (${staffer.role}, ${staffer.tenure_months}mo). Contract deadline ${ct.contract.deadline}, fill=${ct.contract.fill_requirement}.`,
})),
};
const fname = `${staffer.id}_${ct.tag}.json`;
await writeFile(join(outDir, fname), JSON.stringify(spec, null, 2));
manifest.push({ file: fname, staffer: staffer.name, contract: ct.tag, client: ct.client });
}
}
await writeFile(
join(outDir, "manifest.json"),
JSON.stringify({ count: manifest.length, scenarios: manifest }, null, 2),
);
console.log(`${manifest.length} staffer-demo specs → ${outDir}/`);
for (const m of manifest) console.log(` ${m.file}${m.staffer} × ${m.contract}`);
}
main().catch(e => {
console.error("gen_staffer_demo failed:", (e as Error).message);
process.exit(1);
});

View File

@ -34,6 +34,7 @@ const OUTCOMES_FILE = "outcomes.jsonl";
const CONFIG_SNAPSHOTS_FILE = "config_snapshots.jsonl";
const ERROR_CORRECTIONS_FILE = "error_corrections.jsonl";
const RECOMMENDATIONS_FILE = "pathway_recommendations.jsonl";
const STAFFERS_FILE = "staffers.jsonl";
// What a playbook signature looks like — stable hash of the scenario
// shape that ignores timestamps and specific worker IDs. Two runs with
@ -60,11 +61,19 @@ export interface RunOutcome {
overview: string;
overview_cloud: boolean;
};
staffer?: { // Phase 23 — who ran this scenario
id: string;
name: string;
tenure_months: number;
role: string;
};
ok_events: number;
total_events: number;
total_turns: number;
total_gap_signals: number;
total_citations: number;
rescue_attempts: number; // Phase 22 item B
rescue_successes: number;
per_event: Array<{
at: string;
kind: string;
@ -78,6 +87,27 @@ export interface RunOutcome {
created_at: string;
}
// Per-staffer aggregate. Recomputed from outcomes.jsonl after every
// run. Competence_score weights neighbor retrieval so Senior staffers'
// playbooks rank higher for similar scenarios than Junior staffers'.
export interface StafferStats {
id: string;
name: string;
tenure_months: number;
role: string;
total_runs: number;
total_events_attempted: number;
total_events_ok: number;
fill_rate: number; // ok / attempted
avg_turns_per_event: number;
avg_citations_per_run: number;
rescue_attempts: number;
rescue_successes: number;
rescue_rate: number;
competence_score: number; // 0.0 - 1.0, see formula below
last_updated: string;
}
// The AI-synthesized recommendation written back for future runs.
export interface PathwayRecommendation {
sig_hash: string;
@ -142,7 +172,7 @@ async function readJsonl<T>(file: string): Promise<T[]> {
// embedding, appends outcome, updates or inserts signature entry.
export async function indexRun(
scenarioDir: string,
spec: { client: string; date: string; events: Array<any> },
spec: { client: string; date: string; events: Array<any>; staffer?: { id: string; name: string; tenure_months: number; role: string } },
models: { executor: string; reviewer: string; overview: string; overview_cloud: boolean },
elapsed_secs: number,
): Promise<{ sig_hash: string; outcome: RunOutcome }> {
@ -154,16 +184,21 @@ export async function indexRun(
// Read results.json produced by scenario.ts to build the outcome record.
const resultsRaw = await readFile(join(scenarioDir, "results.json"), "utf8");
const results = JSON.parse(resultsRaw) as any[];
const rescue_attempts = results.filter(r => r.retry_remediation).length;
const rescue_successes = results.filter(r => r.retry_remediation && r.ok).length;
const outcome: RunOutcome = {
sig_hash,
run_id: scenarioDir.split("/").pop() ?? scenarioDir,
date: spec.date,
models,
staffer: spec.staffer,
ok_events: results.filter(r => r.ok).length,
total_events: results.length,
total_turns: results.reduce((s, r) => s + (r.turns ?? 0), 0),
total_gap_signals: results.reduce((s, r) => s + (r.gap_signals?.length ?? 0), 0),
total_citations: results.reduce((s, r) => s + (r.playbook_citations?.length ?? 0), 0),
rescue_attempts,
rescue_successes,
per_event: results.map(r => ({
at: r.event.at,
kind: r.event.kind,
@ -178,6 +213,13 @@ export async function indexRun(
};
await appendFile(join(KB_DIR, OUTCOMES_FILE), JSON.stringify(outcome) + "\n");
// Phase 23 — recompute this staffer's aggregate + competence_score.
// Cheap until we have thousands of runs; swap to streaming aggregate
// when that becomes a concern.
if (spec.staffer) {
await recomputeStafferStats(spec.staffer.id);
}
// Embed + upsert signature. Skip if embedding fails — the outcome is
// still persisted, just without neighbor-search hookup.
try {
@ -221,6 +263,72 @@ export async function indexRun(
return { sig_hash, outcome };
}
// Phase 23 — per-staffer aggregate, recomputed from scratch on each
// run. Writes the full table to STAFFERS_FILE (not append-only; we
// always want the current-state snapshot). Competence score is bounded
// 0..1 and combines four dimensions:
// fill_rate — how often the staffer completes their events
// turn_efficiency — lower turn counts are better
// citation_density — signals use of playbook_memory feedback
// rescue_rate — cloud rescue successes per attempt (doesn't
// penalize staffers who never needed one)
// Weights: fill 0.45, turn_eff 0.20, citation 0.20, rescue 0.15.
// Rationale: completing the job matters most; everything else is style.
export async function recomputeStafferStats(staffer_id: string): Promise<StafferStats | null> {
const outcomes = await readJsonl<RunOutcome>(OUTCOMES_FILE);
const mine = outcomes.filter(o => o.staffer?.id === staffer_id);
if (mine.length === 0) return null;
const latest = mine[mine.length - 1].staffer!;
const total_events_attempted = mine.reduce((s, o) => s + o.total_events, 0);
const total_events_ok = mine.reduce((s, o) => s + o.ok_events, 0);
const total_turns = mine.reduce((s, o) => s + o.total_turns, 0);
const total_citations = mine.reduce((s, o) => s + o.total_citations, 0);
const rescue_attempts = mine.reduce((s, o) => s + (o.rescue_attempts ?? 0), 0);
const rescue_successes = mine.reduce((s, o) => s + (o.rescue_successes ?? 0), 0);
const fill_rate = total_events_attempted > 0 ? total_events_ok / total_events_attempted : 0;
const avg_turns_per_event = total_events_attempted > 0 ? total_turns / total_events_attempted : 0;
const avg_citations_per_run = mine.length > 0 ? total_citations / mine.length : 0;
const rescue_rate = rescue_attempts > 0 ? rescue_successes / rescue_attempts : 1.0; // never-rescued defaults to perfect
// Normalize each axis to 0..1. Caps chosen from observed distributions.
const turn_eff = avg_turns_per_event === 0 ? 0 : Math.max(0, 1 - Math.min(avg_turns_per_event / 10, 1));
const cite_norm = Math.min(avg_citations_per_run / 3, 1);
const competence_score = 0.45 * fill_rate
+ 0.20 * turn_eff
+ 0.20 * cite_norm
+ 0.15 * rescue_rate;
const stats: StafferStats = {
id: staffer_id,
name: latest.name,
tenure_months: latest.tenure_months,
role: latest.role,
total_runs: mine.length,
total_events_attempted,
total_events_ok,
fill_rate,
avg_turns_per_event,
avg_citations_per_run,
rescue_attempts,
rescue_successes,
rescue_rate,
competence_score,
last_updated: new Date().toISOString(),
};
// Rewrite whole file — cheap at O(staffers) scale.
const existing = await readJsonl<StafferStats>(STAFFERS_FILE);
const others = existing.filter(s => s.id !== staffer_id);
others.push(stats);
await writeFile(
join(KB_DIR, STAFFERS_FILE),
others.map(s => JSON.stringify(s)).join("\n") + "\n",
);
return stats;
}
// Public accessor — used by findNeighbors + the staffer report script.
export async function loadStafferStats(): Promise<StafferStats[]> {
return readJsonl<StafferStats>(STAFFERS_FILE);
}
// Cosine similarity for neighbor lookup. Float32-in-memory is fine for
// O(thousands) signatures; swap to vectord HNSW once the corpus grows.
function cosine(a: number[], b: number[]): number {
@ -237,9 +345,18 @@ function cosine(a: number[], b: number[]): number {
// Find the k nearest-neighbor signatures for a target spec, returning
// neighbor sigs + their outcome history. This is what the recommender
// feeds to the overview model.
//
// Phase 23 — weighted by staffer competence. The ranking score is
// cosine_similarity * max_competence_among_this_sig's_outcomes. Top
// staffers' playbooks surface first even if their scenario was
// slightly less similar than a junior's. Sigs with no staffer history
// fall back to raw similarity (competence defaults to 0.5).
export async function findNeighbors(spec: any, k = 5): Promise<Array<{
sig: PlaybookSignature;
similarity: number;
weighted_score: number;
best_staffer_competence: number;
best_staffer_id: string | null;
outcomes: RunOutcome[];
}>> {
await ensureKb();
@ -256,16 +373,45 @@ export async function findNeighbors(spec: any, k = 5): Promise<Array<{
const sigs = await readJsonl<PlaybookSignature>(SIGNATURES_FILE);
const outcomes = await readJsonl<RunOutcome>(OUTCOMES_FILE);
const staffers = await readJsonl<StafferStats>(STAFFERS_FILE);
const competenceById = new Map(staffers.map(s => [s.id, s.competence_score]));
// Per-sig best staffer — the highest-competence coordinator who has
// ever run this signature. Used to weight the sig's ranking.
function bestStafferFor(sig_hash: string): { id: string | null; competence: number } {
const mine = outcomes.filter(o => o.sig_hash === sig_hash && o.staffer?.id);
if (mine.length === 0) return { id: null, competence: 0.5 };
let bestId: string | null = null;
let bestComp = 0;
for (const o of mine) {
const c = competenceById.get(o.staffer!.id) ?? 0.5;
if (c > bestComp) { bestComp = c; bestId = o.staffer!.id; }
}
return { id: bestId, competence: bestComp };
}
const ranked = sigs
.filter(s => s.sig_hash !== targetHash) // don't recommend against self
.map(s => ({ sig: s, similarity: cosine(targetVec, s.embedding) }))
.sort((a, b) => b.similarity - a.similarity)
.map(s => {
const similarity = cosine(targetVec, s.embedding);
const best = bestStafferFor(s.sig_hash);
// Weighted score: similarity multiplied by the best staffer's
// competence (floored at 0.3 so a sig with a low-competence
// staffer still shows up if similarity is very high).
const weight = Math.max(best.competence, 0.3);
return {
sig: s,
similarity,
weighted_score: similarity * weight,
best_staffer_competence: best.competence,
best_staffer_id: best.id,
};
})
.sort((a, b) => b.weighted_score - a.weighted_score)
.slice(0, k);
return ranked.map(r => ({
sig: r.sig,
similarity: r.similarity,
...r,
outcomes: outcomes.filter(o => o.sig_hash === r.sig.sig_hash),
}));
}
@ -342,6 +488,8 @@ export async function recommendFor(
// Build the prompt. Include target spec digest, neighbor digests with
// their outcome stats, and recent error corrections. Ask for
// structured output so we can parse it.
const staffers = await readJsonl<StafferStats>(STAFFERS_FILE);
const stafferById = new Map(staffers.map(s => [s.id, s]));
const neighborBlock = neighbors.map(n => {
const best = n.outcomes.reduce((a, b) =>
a && a.ok_events / Math.max(1, a.total_events) >= b.ok_events / Math.max(1, b.total_events) ? a : b,
@ -349,7 +497,11 @@ export async function recommendFor(
const avgOk = n.outcomes.length > 0
? (n.outcomes.reduce((s, o) => s + o.ok_events, 0) / n.outcomes.length).toFixed(1)
: "?";
return `- sig ${n.sig.sig_hash} sim=${n.similarity.toFixed(3)} (${n.sig.events_digest.slice(0, 100)}): ${n.outcomes.length} runs, avg ${avgOk}/${best?.total_events ?? "?"} ok; best models: exec=${best?.models.executor ?? "?"} review=${best?.models.reviewer ?? "?"}`;
const topStaffer = n.best_staffer_id ? stafferById.get(n.best_staffer_id) : null;
const stafferTag = topStaffer
? ` [top staffer: ${topStaffer.name} (${topStaffer.role}, competence=${topStaffer.competence_score.toFixed(2)})]`
: "";
return `- sig ${n.sig.sig_hash} sim=${n.similarity.toFixed(3)} weighted=${n.weighted_score.toFixed(3)}${stafferTag}: ${n.outcomes.length} runs, avg ${avgOk}/${best?.total_events ?? "?"} ok; best models: exec=${best?.models.executor ?? "?"} review=${best?.models.reviewer ?? "?"}`;
}).join("\n");
const correctionBlock = corrections.slice(-3).map(c =>

View File

@ -122,10 +122,40 @@ interface FillEvent {
replaces_event?: string; // misplacement back-ref for reporting
}
// Contract terms describe the business constraints around a scenario:
// how much can the client pay, by when, and how is a local candidate
// bonused vs an out-of-area one. T3 checkpoint + cloud rescue pass
// these into the overseer's prompt so pivots respect budget (not just
// geography). Optional — legacy scenarios without a contract degrade
// to the original "nearest-city" pivot logic.
interface ContractTerms {
deadline: string; // ISO date — "2026-05-05"
budget_total_usd?: number; // optional total cap across the contract
budget_per_hour_max?: number; // per-worker hourly cap
local_bonus_per_hour?: number; // extra $/hr for in-radius candidates
local_bonus_radius_mi?: number; // radius from the contract city
fill_requirement?: "paramount" | "preferred"; // "paramount" = must fill;
// "preferred" = best-effort
}
// Phase 23 — staffer identity. When a scenario is assigned to a
// specific coordinator, we record their trajectory so KB can
// weight future retrieval by competence. Junior staffers inherit
// Senior staffers' playbooks; top staffers become the training
// signal the system auto-discovers.
interface Staffer {
id: string; // "S-001"
name: string; // "Maria Chen"
tenure_months: number;
role: "senior" | "mid" | "junior" | "trainee";
}
interface ScenarioSpec {
client: string;
date: string;
events: FillEvent[];
contract?: ContractTerms;
staffer?: Staffer;
}
interface EventResult {
@ -167,6 +197,7 @@ interface EventResult {
interface CloudRemediation {
retry: boolean;
new_city?: string;
new_state?: string;
new_role?: string;
new_count?: number;
rationale: string;
@ -957,10 +988,25 @@ function extractDiagnostics(log: LogEntry[] | undefined): {
return { sql_filters, hybrid_row_counts, sql_errors, drift_reasons };
}
// Render contract terms into a prompt-friendly block. Empty string when
// no contract is attached — keeps legacy scenarios unaffected.
function contractBlock(contract: ContractTerms | undefined): string {
if (!contract) return "";
const parts: string[] = [];
parts.push(`deadline=${contract.deadline}`);
if (contract.fill_requirement) parts.push(`fill=${contract.fill_requirement}`);
if (contract.budget_per_hour_max) parts.push(`budget/hr max=$${contract.budget_per_hour_max}`);
if (contract.budget_total_usd) parts.push(`total budget=$${contract.budget_total_usd}`);
if (contract.local_bonus_per_hour) parts.push(`local bonus=+$${contract.local_bonus_per_hour}/hr`);
if (contract.local_bonus_radius_mi) parts.push(`local radius=${contract.local_bonus_radius_mi}mi`);
return `\nCONTRACT TERMS: ${parts.join(", ")}`;
}
async function runOverviewCheckpoint(
event: FillEvent,
result: EventResult,
prior: EventResult[],
contract?: ContractTerms,
): Promise<OverviewCheckpoint | null> {
if (T3_DISABLED) return null;
const start = Date.now();
@ -985,13 +1031,13 @@ async function runOverviewCheckpoint(
+ `Gap signals: ${result.gap_signals.join("; ") || "none"}.`;
const prompt = `You are the overview reviewer for a staffing coordinator agent system. A mid-day checkpoint has been triggered.
${contractBlock(contract)}
Recent events (most recent last):
${priorSummary || "(no prior events)"}
${thisOne}${diagBlock}
Your job: emit ONE risk flag (8 words) and ONE actionable hint (40 words) for the NEXT event. Be concrete: name the role, city, worker class, OR a geographic pivot (e.g. "pivot Gary IN → Chicago IL, 40min drive"). Do not restate what happened. If the failure was zero-supply, your hint MUST propose a specific alternative city or role. Think step by step, then output strictly as:
Your job: emit ONE risk flag (8 words) and ONE actionable hint (40 words) for the NEXT event. Be concrete: name the role, city, worker class, OR a geographic pivot (e.g. "pivot to {city}, {state} ({distance}mi) — still in bonus radius"). Do not restate what happened. If the failure was zero-supply, your hint MUST propose a specific alternative city or role. If contract has local_bonus_radius_mi, prefer alternates within that radius before proposing farther pivots. Think step by step, then output strictly as:
RISK: <flag>
HINT: <hint>`;
@ -1036,6 +1082,7 @@ HINT: <hint>`;
async function requestCloudRemediation(
event: FillEvent,
result: EventResult,
contract?: ContractTerms,
): Promise<{ remediation: CloudRemediation; duration_secs: number } | null> {
if (T3_DISABLED) return null;
const start = Date.now();
@ -1054,6 +1101,7 @@ FAILED EVENT:
outcome: ${result.error ?? "unknown failure"}
turns used: ${result.turns}
pool surfaced: ${result.pool_size ?? "n/a"}
${contractBlock(contract)}
RAW DIAGNOSTICS (what the agent actually saw):
${diagBlock}
@ -1062,6 +1110,7 @@ Respond with a JSON object (NOTHING else, no prose before or after, no markdown)
{
"retry": true | false,
"new_city": "string (same as original if no pivot)",
"new_state": "XX (two-letter abbreviation)",
"new_role": "string (same as original if no pivot)",
"new_count": <integer (same as original if no pivot)>,
"rationale": "2-3 sentences explaining the fix or why retry is futile"
@ -1072,7 +1121,9 @@ RULES:
- If the city has genuine zero supply, pivot to the NEAREST alternate city with comparable labor pool (name a specific one).
- If the role is uniquely scarce, either broaden to a synonym role OR reduce count to something achievable.
- If no pivot seems viable, set retry=false wasting a retry is worse than declaring impossible.
- Keep new_count realistic. Don't propose 5× in a city that clearly only has 2 workers.`;
- Keep new_count realistic. Don't propose 5× in a city that clearly only has 2 workers.
- new_city is the CITY name only (e.g. "Clarksville"). Put the two-letter state in new_state. Don't concat them.
${contract ? `- CONTRACT AWARENESS: fill_requirement=${contract.fill_requirement ?? "preferred"}. ${contract.fill_requirement === "paramount" ? "MUST fill — splitting across more cities is acceptable if one city can't cover headcount." : "Best-effort — declining is OK if budget can't absorb pivot premium."} ${contract.local_bonus_radius_mi ? `Local bonus radius is ${contract.local_bonus_radius_mi}mi from ${event.city}, ${event.state}; prefer pivots WITHIN that radius even if they have slightly less supply, since those candidates earn the local bonus premium.` : ""} ${contract.budget_per_hour_max ? `Per-hour budget max is $${contract.budget_per_hour_max}.` : ""}` : ""}`;
let raw = "";
try {
@ -1108,7 +1159,7 @@ async function runCrossDayLesson(ctx: ScenarioContext, checkpoints: OverviewChec
const prompt = `You are the end-of-day lesson writer for a staffing coordinator agent system. The day is done. Distill it.
Client: ${ctx.spec.client} Date: ${ctx.spec.date}
Client: ${ctx.spec.client} Date: ${ctx.spec.date}${contractBlock(ctx.spec.contract)}
Events that ran:
${eventDigest}
@ -1326,6 +1377,13 @@ async function main() {
const checkpoints: OverviewCheckpoint[] = [];
console.log(`▶ scenario: ${spec.client}, ${spec.date}, ${spec.events.length} events`);
if (spec.staffer) {
console.log(`▶ staffer: ${spec.staffer.id} ${spec.staffer.name} (${spec.staffer.role}, ${spec.staffer.tenure_months}mo)`);
}
if (spec.contract) {
const c = spec.contract;
console.log(`▶ contract: deadline=${c.deadline} fill=${c.fill_requirement ?? "preferred"}${c.budget_per_hour_max ? ` budget=$${c.budget_per_hour_max}/hr` : ""}${c.local_bonus_radius_mi ? ` local_radius=${c.local_bonus_radius_mi}mi+$${c.local_bonus_per_hour ?? 0}` : ""}`);
}
console.log(`▶ models: exec=${EXECUTOR_MODEL} review=${REVIEWER_MODEL} overview=${T3_DISABLED ? "disabled" : OVERVIEW_MODEL + (OVERVIEW_CLOUD ? " (cloud)" : "")}`);
console.log(`▶ out: ${out_dir}\n`);
@ -1363,26 +1421,21 @@ async function main() {
// scenarios.
if (!result.ok && RETRY_ON_FAIL && !T3_DISABLED) {
console.log(` ▶ cloud rescue requested for ${event.at} ${event.kind}`);
const rescue = await requestCloudRemediation(event, result);
const rescue = await requestCloudRemediation(event, result, spec.contract);
if (rescue && rescue.remediation.retry) {
const r = rescue.remediation;
// Sanitize cloud's fields — model sometimes emits "Hammond, IN"
// as new_city and "IN" as new_state, producing "Hammond, IN, IN"
// downstream. Split on comma and take the first token for city.
const sanitizeCity = (c: string | undefined) => (c ?? "").split(",")[0].trim();
const sanitizeState = (c: string | undefined, stateFromCity: string) => {
const explicit = (c ?? "").trim();
// If explicit state is empty or matches original, try to
// extract from the city string if it had a trailing ", XX".
return explicit || stateFromCity || event.state;
};
const cityRaw = r.new_city ?? event.city;
const cityClean = sanitizeCity(cityRaw);
const stateFromCity = (cityRaw.match(/,\s*([A-Z]{2})/) ?? [])[1] ?? "";
// Sanitize cloud's fields — model sometimes still packs state
// into city ("Hammond, IN") even when prompted to split; guard
// by stripping comma+ from new_city and harvesting the trailing
// state if new_state is missing.
const cityRaw = (r.new_city ?? event.city).trim();
const cityParts = cityRaw.split(",").map(s => s.trim());
const cityClean = cityParts[0] || event.city;
const stateFromCity = cityParts[1]?.match(/^([A-Z]{2})/i)?.[1]?.toUpperCase() ?? "";
const newEvent: FillEvent = {
...event,
city: cityClean || event.city,
state: sanitizeState(undefined, stateFromCity) || event.state,
city: cityClean,
state: (r.new_state?.trim() || stateFromCity || event.state).toUpperCase(),
role: r.new_role ?? event.role,
count: r.new_count ?? event.count,
scenario_note: `[cloud-rescue ${rescue.duration_secs.toFixed(1)}s] ${r.rationale}`,
@ -1455,7 +1508,7 @@ async function main() {
const nthHit = T3_CHECKPOINT_EVERY > 0 && ((i + 1) % T3_CHECKPOINT_EVERY === 0);
const shouldCheckpoint = !T3_DISABLED && (event.kind === "misplacement" || nthHit || isLast);
if (shouldCheckpoint) {
const cp = await runOverviewCheckpoint(event, result, ctx.results.slice(0, -1));
const cp = await runOverviewCheckpoint(event, result, ctx.results.slice(0, -1), spec.contract);
if (cp) {
checkpoints.push(cp);
await appendFile(join(out_dir, "checkpoints.jsonl"), JSON.stringify(cp) + "\n");
@ -1532,12 +1585,17 @@ async function main() {
// run ends → KB updates → next run reads rec at startup.
try {
const elapsed = (Date.now() - runStart) / 1000;
const { sig_hash } = await indexRun(out_dir, spec, {
executor: EXECUTOR_MODEL,
reviewer: REVIEWER_MODEL,
overview: OVERVIEW_MODEL,
overview_cloud: OVERVIEW_CLOUD,
}, elapsed);
const { sig_hash } = await indexRun(
out_dir,
{ client: spec.client, date: spec.date, events: spec.events, staffer: spec.staffer },
{
executor: EXECUTOR_MODEL,
reviewer: REVIEWER_MODEL,
overview: OVERVIEW_MODEL,
overview_cloud: OVERVIEW_CLOUD,
},
elapsed,
);
console.log(`▶ KB indexed: sig=${sig_hash} (${elapsed.toFixed(1)}s)`);
const newRec = await recommendFor(spec, {
overview_model: OVERVIEW_MODEL,

View File

@ -0,0 +1,126 @@
{
"count": 20,
"seed": 1337,
"scenarios": [
{
"file": "scen_000_Great_Lakes_Mfg_Cincinnati.json",
"client": "Great Lakes Mfg",
"city": "Cincinnati",
"events": 4
},
{
"file": "scen_001_Parallel_Machining_Joliet.json",
"client": "Parallel Machining",
"city": "Joliet",
"events": 2
},
{
"file": "scen_002_Summit_Industrial_Cincinnati.json",
"client": "Summit Industrial",
"city": "Cincinnati",
"events": 3
},
{
"file": "scen_003_Pioneer_Assembly_Chicago.json",
"client": "Pioneer Assembly",
"city": "Chicago",
"events": 1
},
{
"file": "scen_004_Midway_Distribution_Columbus.json",
"client": "Midway Distribution",
"city": "Columbus",
"events": 2
},
{
"file": "scen_005_Apex_Warehouse_Cleveland.json",
"client": "Apex Warehouse",
"city": "Cleveland",
"events": 3
},
{
"file": "scen_006_Pioneer_Assembly_Flint.json",
"client": "Pioneer Assembly",
"city": "Flint",
"events": 5
},
{
"file": "scen_007_Riverfront_Steel_Toledo.json",
"client": "Riverfront Steel",
"city": "Toledo",
"events": 3
},
{
"file": "scen_008_Northland_Logistics_Indianapolis.json",
"client": "Northland Logistics",
"city": "Indianapolis",
"events": 4
},
{
"file": "scen_009_Parallel_Machining_Flint.json",
"client": "Parallel Machining",
"city": "Flint",
"events": 3
},
{
"file": "scen_010_Northland_Logistics_Chicago.json",
"client": "Northland Logistics",
"city": "Chicago",
"events": 2
},
{
"file": "scen_011_Heritage_Foods_Flint.json",
"client": "Heritage Foods",
"city": "Flint",
"events": 3
},
{
"file": "scen_012_Parallel_Machining_Kansas_City.json",
"client": "Parallel Machining",
"city": "Kansas City",
"events": 3
},
{
"file": "scen_013_Horizon_Supply_Flint.json",
"client": "Horizon Supply",
"city": "Flint",
"events": 3
},
{
"file": "scen_014_Midway_Distribution_Indianapolis.json",
"client": "Midway Distribution",
"city": "Indianapolis",
"events": 4
},
{
"file": "scen_015_Cornerstone_Fabrication_Kansas_City.json",
"client": "Cornerstone Fabrication",
"city": "Kansas City",
"events": 4
},
{
"file": "scen_016_Riverfront_Steel_Columbus.json",
"client": "Riverfront Steel",
"city": "Columbus",
"events": 4
},
{
"file": "scen_017_Summit_Industrial_Detroit.json",
"client": "Summit Industrial",
"city": "Detroit",
"events": 2
},
{
"file": "scen_018_Heritage_Foods_Cincinnati.json",
"client": "Heritage Foods",
"city": "Cincinnati",
"events": 4
},
{
"file": "scen_019_Midway_Distribution_Chicago.json",
"client": "Midway Distribution",
"city": "Chicago",
"events": 3
}
]
}

View File

@ -0,0 +1,66 @@
{
"client": "Riverline Logistics — Nashville Downtown Build-Out",
"date": "2026-05-05",
"contract": {
"deadline": "2026-05-19",
"budget_total_usd": 180000,
"budget_per_hour_max": 32,
"local_bonus_per_hour": 4,
"local_bonus_radius_mi": 75,
"fill_requirement": "paramount"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Welder",
"count": 4,
"city": "Nashville",
"state": "TN",
"shift_start": "07:00 AM",
"scenario_note": "Skilled welding for downtown structural assembly. Prefer local (in 75mi). Contract pays up to $32/hr + $4/hr local bonus. Fill is paramount — the contract is worth $180K total, broken = penalty."
},
{
"kind": "expansion",
"at": "08:30",
"role": "Packaging Operator",
"count": 6,
"city": "Nashville",
"state": "TN",
"shift_start": "08:30 AM",
"scenario_note": "Warehouse packaging on-site for the same project. 6 workers preferred Nashville-local; out-of-area acceptable if local pool is exhausted. Respect budget."
},
{
"kind": "baseline_fill",
"at": "09:00",
"role": "Shipping Clerk",
"count": 2,
"city": "Nashville",
"state": "TN",
"shift_start": "09:00 AM",
"scenario_note": "Administrative/shipping coordination role. Two clerks needed; tightening the load on packaging team."
},
{
"kind": "emergency",
"at": "13:00",
"role": "Welder",
"count": 2,
"city": "Nashville",
"state": "TN",
"shift_start": "13:00 PM",
"deadline": "15:00",
"scenario_note": "A subcontractor just dropped out — need 2 more Welders by 3pm. Use cloud rescue path if Nashville supply is exhausted; pivot to within-radius first (if any in 75mi), then budget-permitting out-of-area."
},
{
"kind": "misplacement",
"at": "15:30",
"role": "Packaging Operator",
"count": 1,
"city": "Nashville",
"state": "TN",
"shift_start": "15:30 PM",
"replaces_event": "08:30",
"scenario_note": "One packager no-showed. Single refill. Any Nashville-area candidate, budget already covered."
}
]
}

View File

@ -0,0 +1,43 @@
{
"client": "Great Lakes Mfg",
"date": "2026-04-21",
"events": [
{
"kind": "baseline_fill",
"at": "13:00",
"role": "Material Handler",
"count": 2,
"city": "Cincinnati",
"state": "OH",
"shift_start": "13:00 AM"
},
{
"kind": "recurring",
"at": "14:30",
"role": "Assembler",
"count": 2,
"city": "Cincinnati",
"state": "OH",
"shift_start": "14:30 AM"
},
{
"kind": "emergency",
"at": "10:30",
"role": "Material Handler",
"count": 3,
"city": "Cincinnati",
"state": "OH",
"shift_start": "10:30 AM"
},
{
"kind": "misplacement",
"at": "13:30",
"role": "Shipping Clerk",
"count": 1,
"city": "Cincinnati",
"state": "OH",
"shift_start": "13:30 AM",
"replaces_event": "13:00"
}
]
}

View File

@ -0,0 +1,24 @@
{
"client": "Parallel Machining",
"date": "2026-04-22",
"events": [
{
"kind": "baseline_fill",
"at": "10:00",
"role": "Machine Operator",
"count": 2,
"city": "Joliet",
"state": "IL",
"shift_start": "10:00 AM"
},
{
"kind": "recurring",
"at": "09:30",
"role": "Packer",
"count": 2,
"city": "Joliet",
"state": "IL",
"shift_start": "09:30 AM"
}
]
}

View File

@ -0,0 +1,33 @@
{
"client": "Summit Industrial",
"date": "2026-04-23",
"events": [
{
"kind": "baseline_fill",
"at": "13:30",
"role": "Shipping Clerk",
"count": 1,
"city": "Cincinnati",
"state": "OH",
"shift_start": "13:30 AM"
},
{
"kind": "recurring",
"at": "08:00",
"role": "Loader",
"count": 1,
"city": "Cincinnati",
"state": "OH",
"shift_start": "08:00 AM"
},
{
"kind": "emergency",
"at": "13:00",
"role": "Forklift Operator",
"count": 2,
"city": "Cincinnati",
"state": "OH",
"shift_start": "13:00 AM"
}
]
}

View File

@ -0,0 +1,15 @@
{
"client": "Pioneer Assembly",
"date": "2026-04-24",
"events": [
{
"kind": "baseline_fill",
"at": "14:00",
"role": "Receiving Clerk",
"count": 3,
"city": "Chicago",
"state": "IL",
"shift_start": "14:00 AM"
}
]
}

View File

@ -0,0 +1,24 @@
{
"client": "Midway Distribution",
"date": "2026-04-25",
"events": [
{
"kind": "baseline_fill",
"at": "09:30",
"role": "Forklift Operator",
"count": 1,
"city": "Columbus",
"state": "OH",
"shift_start": "09:30 AM"
},
{
"kind": "expansion",
"at": "13:00",
"role": "Assembler",
"count": 4,
"city": "Columbus",
"state": "OH",
"shift_start": "13:00 AM"
}
]
}

View File

@ -0,0 +1,33 @@
{
"client": "Apex Warehouse",
"date": "2026-04-26",
"events": [
{
"kind": "baseline_fill",
"at": "10:30",
"role": "Receiving Clerk",
"count": 1,
"city": "Cleveland",
"state": "OH",
"shift_start": "10:30 AM"
},
{
"kind": "recurring",
"at": "15:30",
"role": "Quality Tech",
"count": 2,
"city": "Cleveland",
"state": "OH",
"shift_start": "15:30 AM"
},
{
"kind": "expansion",
"at": "14:30",
"role": "Machine Operator",
"count": 5,
"city": "Cleveland",
"state": "OH",
"shift_start": "14:30 AM"
}
]
}

View File

@ -0,0 +1,52 @@
{
"client": "Pioneer Assembly",
"date": "2026-04-27",
"events": [
{
"kind": "baseline_fill",
"at": "13:30",
"role": "CNC Operator",
"count": 2,
"city": "Flint",
"state": "MI",
"shift_start": "13:30 AM"
},
{
"kind": "recurring",
"at": "11:30",
"role": "Loader",
"count": 1,
"city": "Flint",
"state": "MI",
"shift_start": "11:30 AM"
},
{
"kind": "expansion",
"at": "14:00",
"role": "Welder",
"count": 3,
"city": "Flint",
"state": "MI",
"shift_start": "14:00 AM"
},
{
"kind": "emergency",
"at": "12:30",
"role": "Machine Operator",
"count": 2,
"city": "Flint",
"state": "MI",
"shift_start": "12:30 AM"
},
{
"kind": "misplacement",
"at": "17:00",
"role": "Shipping Clerk",
"count": 1,
"city": "Flint",
"state": "MI",
"shift_start": "17:00 AM",
"replaces_event": "13:30"
}
]
}

View File

@ -0,0 +1,34 @@
{
"client": "Riverfront Steel",
"date": "2026-04-28",
"events": [
{
"kind": "baseline_fill",
"at": "11:00",
"role": "Assembler",
"count": 3,
"city": "Toledo",
"state": "OH",
"shift_start": "11:00 AM"
},
{
"kind": "recurring",
"at": "14:00",
"role": "Material Handler",
"count": 1,
"city": "Toledo",
"state": "OH",
"shift_start": "14:00 AM"
},
{
"kind": "misplacement",
"at": "08:30",
"role": "Packer",
"count": 1,
"city": "Toledo",
"state": "OH",
"shift_start": "08:30 AM",
"replaces_event": "11:00"
}
]
}

View File

@ -0,0 +1,43 @@
{
"client": "Northland Logistics",
"date": "2026-04-29",
"events": [
{
"kind": "baseline_fill",
"at": "14:00",
"role": "Quality Tech",
"count": 1,
"city": "Indianapolis",
"state": "IN",
"shift_start": "14:00 AM"
},
{
"kind": "recurring",
"at": "12:30",
"role": "Shipping Clerk",
"count": 1,
"city": "Indianapolis",
"state": "IN",
"shift_start": "12:30 AM"
},
{
"kind": "emergency",
"at": "10:00",
"role": "Welder",
"count": 2,
"city": "Indianapolis",
"state": "IN",
"shift_start": "10:00 AM"
},
{
"kind": "misplacement",
"at": "14:30",
"role": "Material Handler",
"count": 1,
"city": "Indianapolis",
"state": "IN",
"shift_start": "14:30 AM",
"replaces_event": "14:00"
}
]
}

View File

@ -0,0 +1,33 @@
{
"client": "Parallel Machining",
"date": "2026-04-30",
"events": [
{
"kind": "baseline_fill",
"at": "16:00",
"role": "Loader",
"count": 3,
"city": "Flint",
"state": "MI",
"shift_start": "16:00 AM"
},
{
"kind": "recurring",
"at": "09:30",
"role": "Warehouse Associate",
"count": 2,
"city": "Flint",
"state": "MI",
"shift_start": "09:30 AM"
},
{
"kind": "emergency",
"at": "12:30",
"role": "Packer",
"count": 3,
"city": "Flint",
"state": "MI",
"shift_start": "12:30 AM"
}
]
}

View File

@ -0,0 +1,24 @@
{
"client": "Northland Logistics",
"date": "2026-05-01",
"events": [
{
"kind": "baseline_fill",
"at": "15:00",
"role": "Shipping Clerk",
"count": 1,
"city": "Chicago",
"state": "IL",
"shift_start": "15:00 AM"
},
{
"kind": "expansion",
"at": "10:00",
"role": "Warehouse Associate",
"count": 2,
"city": "Chicago",
"state": "IL",
"shift_start": "10:00 AM"
}
]
}

View File

@ -0,0 +1,33 @@
{
"client": "Heritage Foods",
"date": "2026-05-02",
"events": [
{
"kind": "baseline_fill",
"at": "10:00",
"role": "Receiving Clerk",
"count": 3,
"city": "Flint",
"state": "MI",
"shift_start": "10:00 AM"
},
{
"kind": "expansion",
"at": "14:30",
"role": "Shipping Clerk",
"count": 4,
"city": "Flint",
"state": "MI",
"shift_start": "14:30 AM"
},
{
"kind": "emergency",
"at": "08:30",
"role": "Assembler",
"count": 3,
"city": "Flint",
"state": "MI",
"shift_start": "08:30 AM"
}
]
}

View File

@ -0,0 +1,33 @@
{
"client": "Parallel Machining",
"date": "2026-05-03",
"events": [
{
"kind": "baseline_fill",
"at": "08:00",
"role": "Warehouse Associate",
"count": 2,
"city": "Kansas City",
"state": "MO",
"shift_start": "08:00 AM"
},
{
"kind": "recurring",
"at": "11:30",
"role": "Material Handler",
"count": 2,
"city": "Kansas City",
"state": "MO",
"shift_start": "11:30 AM"
},
{
"kind": "expansion",
"at": "09:00",
"role": "Warehouse Associate",
"count": 5,
"city": "Kansas City",
"state": "MO",
"shift_start": "09:00 AM"
}
]
}

View File

@ -0,0 +1,33 @@
{
"client": "Horizon Supply",
"date": "2026-05-04",
"events": [
{
"kind": "baseline_fill",
"at": "11:00",
"role": "Forklift Operator",
"count": 1,
"city": "Flint",
"state": "MI",
"shift_start": "11:00 AM"
},
{
"kind": "recurring",
"at": "10:30",
"role": "CNC Operator",
"count": 1,
"city": "Flint",
"state": "MI",
"shift_start": "10:30 AM"
},
{
"kind": "emergency",
"at": "16:30",
"role": "Receiving Clerk",
"count": 3,
"city": "Flint",
"state": "MI",
"shift_start": "16:30 AM"
}
]
}

View File

@ -0,0 +1,42 @@
{
"client": "Midway Distribution",
"date": "2026-05-05",
"events": [
{
"kind": "baseline_fill",
"at": "16:00",
"role": "Assembler",
"count": 2,
"city": "Indianapolis",
"state": "IN",
"shift_start": "16:00 AM"
},
{
"kind": "recurring",
"at": "17:30",
"role": "Loader",
"count": 2,
"city": "Indianapolis",
"state": "IN",
"shift_start": "17:30 AM"
},
{
"kind": "expansion",
"at": "10:30",
"role": "Packer",
"count": 5,
"city": "Indianapolis",
"state": "IN",
"shift_start": "10:30 AM"
},
{
"kind": "emergency",
"at": "12:00",
"role": "Loader",
"count": 4,
"city": "Indianapolis",
"state": "IN",
"shift_start": "12:00 AM"
}
]
}

View File

@ -0,0 +1,43 @@
{
"client": "Cornerstone Fabrication",
"date": "2026-05-06",
"events": [
{
"kind": "baseline_fill",
"at": "14:00",
"role": "Warehouse Associate",
"count": 2,
"city": "Kansas City",
"state": "MO",
"shift_start": "14:00 AM"
},
{
"kind": "recurring",
"at": "17:30",
"role": "Loader",
"count": 1,
"city": "Kansas City",
"state": "MO",
"shift_start": "17:30 AM"
},
{
"kind": "emergency",
"at": "12:00",
"role": "Packer",
"count": 3,
"city": "Kansas City",
"state": "MO",
"shift_start": "12:00 AM"
},
{
"kind": "misplacement",
"at": "16:30",
"role": "Assembler",
"count": 1,
"city": "Kansas City",
"state": "MO",
"shift_start": "16:30 AM",
"replaces_event": "14:00"
}
]
}

View File

@ -0,0 +1,43 @@
{
"client": "Riverfront Steel",
"date": "2026-05-07",
"events": [
{
"kind": "baseline_fill",
"at": "12:00",
"role": "Quality Tech",
"count": 3,
"city": "Columbus",
"state": "OH",
"shift_start": "12:00 AM"
},
{
"kind": "recurring",
"at": "09:30",
"role": "Machine Operator",
"count": 1,
"city": "Columbus",
"state": "OH",
"shift_start": "09:30 AM"
},
{
"kind": "emergency",
"at": "17:30",
"role": "Assembler",
"count": 3,
"city": "Columbus",
"state": "OH",
"shift_start": "17:30 AM"
},
{
"kind": "misplacement",
"at": "15:30",
"role": "Material Handler",
"count": 1,
"city": "Columbus",
"state": "OH",
"shift_start": "15:30 AM",
"replaces_event": "12:00"
}
]
}

View File

@ -0,0 +1,24 @@
{
"client": "Summit Industrial",
"date": "2026-05-08",
"events": [
{
"kind": "baseline_fill",
"at": "13:00",
"role": "Warehouse Associate",
"count": 1,
"city": "Detroit",
"state": "MI",
"shift_start": "13:00 AM"
},
{
"kind": "recurring",
"at": "10:30",
"role": "Material Handler",
"count": 1,
"city": "Detroit",
"state": "MI",
"shift_start": "10:30 AM"
}
]
}

View File

@ -0,0 +1,43 @@
{
"client": "Heritage Foods",
"date": "2026-05-09",
"events": [
{
"kind": "baseline_fill",
"at": "12:00",
"role": "Assembler",
"count": 1,
"city": "Cincinnati",
"state": "OH",
"shift_start": "12:00 AM"
},
{
"kind": "recurring",
"at": "17:30",
"role": "Welder",
"count": 1,
"city": "Cincinnati",
"state": "OH",
"shift_start": "17:30 AM"
},
{
"kind": "emergency",
"at": "13:30",
"role": "Material Handler",
"count": 2,
"city": "Cincinnati",
"state": "OH",
"shift_start": "13:30 AM"
},
{
"kind": "misplacement",
"at": "12:00",
"role": "Receiving Clerk",
"count": 1,
"city": "Cincinnati",
"state": "OH",
"shift_start": "12:00 AM",
"replaces_event": "12:00"
}
]
}

View File

@ -0,0 +1,34 @@
{
"client": "Midway Distribution",
"date": "2026-05-10",
"events": [
{
"kind": "baseline_fill",
"at": "11:00",
"role": "Machine Operator",
"count": 2,
"city": "Chicago",
"state": "IL",
"shift_start": "11:00 AM"
},
{
"kind": "expansion",
"at": "17:00",
"role": "Shipping Clerk",
"count": 2,
"city": "Chicago",
"state": "IL",
"shift_start": "17:00 AM"
},
{
"kind": "misplacement",
"at": "09:30",
"role": "Packer",
"count": 1,
"city": "Chicago",
"state": "IL",
"shift_start": "09:30 AM",
"replaces_event": "11:00"
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Pioneer Assembly — Indianapolis Plant Expansion",
"date": "2026-04-24",
"contract": {
"deadline": "2026-05-26",
"budget_total_usd": 220000,
"budget_per_hour_max": 30,
"local_bonus_per_hour": 5,
"local_bonus_radius_mi": 60,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-001",
"name": "Maria Chen",
"tenure_months": 48,
"role": "senior"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:30",
"role": "Assembler",
"count": 6,
"city": "Indianapolis",
"state": "IN",
"shift_start": "07:30 AM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "recurring",
"at": "09:30",
"role": "Quality Tech",
"count": 2,
"city": "Indianapolis",
"state": "IN",
"shift_start": "09:30 AM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "expansion",
"at": "11:00",
"role": "Machine Operator",
"count": 5,
"city": "Indianapolis",
"state": "IN",
"shift_start": "11:00 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "emergency",
"at": "14:00",
"role": "Machine Operator",
"count": 3,
"deadline": "16:00",
"city": "Indianapolis",
"state": "IN",
"shift_start": "14:00 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "misplacement",
"at": "16:00",
"role": "Assembler",
"count": 1,
"replaces_event": "07:30",
"city": "Indianapolis",
"state": "IN",
"shift_start": "16:00 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-26, fill=paramount."
}
]
}

View File

@ -0,0 +1,61 @@
{
"client": "Midway Distribution — Joliet DC Ramp",
"date": "2026-04-23",
"contract": {
"deadline": "2026-05-12",
"budget_total_usd": 120000,
"budget_per_hour_max": 28,
"local_bonus_per_hour": 3,
"local_bonus_radius_mi": 50,
"fill_requirement": "preferred"
},
"staffer": {
"id": "S-001",
"name": "Maria Chen",
"tenure_months": 48,
"role": "senior"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Warehouse Associate",
"count": 5,
"city": "Joliet",
"state": "IL",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "recurring",
"at": "10:00",
"role": "Forklift Operator",
"count": 3,
"city": "Joliet",
"state": "IL",
"shift_start": "10:00 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "expansion",
"at": "12:30",
"role": "Picker",
"count": 4,
"city": "Joliet",
"state": "IL",
"shift_start": "12:30 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "misplacement",
"at": "15:00",
"role": "Forklift Operator",
"count": 1,
"replaces_event": "10:00",
"city": "Joliet",
"state": "IL",
"shift_start": "15:00 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-12, fill=preferred."
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Riverline Logistics — Nashville Downtown Build-Out",
"date": "2026-04-22",
"contract": {
"deadline": "2026-05-19",
"budget_total_usd": 180000,
"budget_per_hour_max": 32,
"local_bonus_per_hour": 4,
"local_bonus_radius_mi": 75,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-001",
"name": "Maria Chen",
"tenure_months": 48,
"role": "senior"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Welder",
"count": 4,
"city": "Nashville",
"state": "TN",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "expansion",
"at": "08:30",
"role": "Packaging Operator",
"count": 6,
"city": "Nashville",
"state": "TN",
"shift_start": "08:30 AM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "baseline_fill",
"at": "09:00",
"role": "Shipping Clerk",
"count": 2,
"city": "Nashville",
"state": "TN",
"shift_start": "09:00 AM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "emergency",
"at": "13:00",
"role": "Welder",
"count": 2,
"deadline": "15:00",
"city": "Nashville",
"state": "TN",
"shift_start": "13:00 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "misplacement",
"at": "15:30",
"role": "Packaging Operator",
"count": 1,
"replaces_event": "08:30",
"city": "Nashville",
"state": "TN",
"shift_start": "15:30 PM",
"scenario_note": "Staffed by Maria Chen (senior, 48mo). Contract deadline 2026-05-19, fill=paramount."
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Pioneer Assembly — Indianapolis Plant Expansion",
"date": "2026-04-27",
"contract": {
"deadline": "2026-05-26",
"budget_total_usd": 220000,
"budget_per_hour_max": 30,
"local_bonus_per_hour": 5,
"local_bonus_radius_mi": 60,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-002",
"name": "James Park",
"tenure_months": 14,
"role": "mid"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:30",
"role": "Assembler",
"count": 6,
"city": "Indianapolis",
"state": "IN",
"shift_start": "07:30 AM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "recurring",
"at": "09:30",
"role": "Quality Tech",
"count": 2,
"city": "Indianapolis",
"state": "IN",
"shift_start": "09:30 AM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "expansion",
"at": "11:00",
"role": "Machine Operator",
"count": 5,
"city": "Indianapolis",
"state": "IN",
"shift_start": "11:00 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "emergency",
"at": "14:00",
"role": "Machine Operator",
"count": 3,
"deadline": "16:00",
"city": "Indianapolis",
"state": "IN",
"shift_start": "14:00 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "misplacement",
"at": "16:00",
"role": "Assembler",
"count": 1,
"replaces_event": "07:30",
"city": "Indianapolis",
"state": "IN",
"shift_start": "16:00 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-26, fill=paramount."
}
]
}

View File

@ -0,0 +1,61 @@
{
"client": "Midway Distribution — Joliet DC Ramp",
"date": "2026-04-26",
"contract": {
"deadline": "2026-05-12",
"budget_total_usd": 120000,
"budget_per_hour_max": 28,
"local_bonus_per_hour": 3,
"local_bonus_radius_mi": 50,
"fill_requirement": "preferred"
},
"staffer": {
"id": "S-002",
"name": "James Park",
"tenure_months": 14,
"role": "mid"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Warehouse Associate",
"count": 5,
"city": "Joliet",
"state": "IL",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "recurring",
"at": "10:00",
"role": "Forklift Operator",
"count": 3,
"city": "Joliet",
"state": "IL",
"shift_start": "10:00 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "expansion",
"at": "12:30",
"role": "Picker",
"count": 4,
"city": "Joliet",
"state": "IL",
"shift_start": "12:30 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "misplacement",
"at": "15:00",
"role": "Forklift Operator",
"count": 1,
"replaces_event": "10:00",
"city": "Joliet",
"state": "IL",
"shift_start": "15:00 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-12, fill=preferred."
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Riverline Logistics — Nashville Downtown Build-Out",
"date": "2026-04-25",
"contract": {
"deadline": "2026-05-19",
"budget_total_usd": 180000,
"budget_per_hour_max": 32,
"local_bonus_per_hour": 4,
"local_bonus_radius_mi": 75,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-002",
"name": "James Park",
"tenure_months": 14,
"role": "mid"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Welder",
"count": 4,
"city": "Nashville",
"state": "TN",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "expansion",
"at": "08:30",
"role": "Packaging Operator",
"count": 6,
"city": "Nashville",
"state": "TN",
"shift_start": "08:30 AM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "baseline_fill",
"at": "09:00",
"role": "Shipping Clerk",
"count": 2,
"city": "Nashville",
"state": "TN",
"shift_start": "09:00 AM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "emergency",
"at": "13:00",
"role": "Welder",
"count": 2,
"deadline": "15:00",
"city": "Nashville",
"state": "TN",
"shift_start": "13:00 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "misplacement",
"at": "15:30",
"role": "Packaging Operator",
"count": 1,
"replaces_event": "08:30",
"city": "Nashville",
"state": "TN",
"shift_start": "15:30 PM",
"scenario_note": "Staffed by James Park (mid, 14mo). Contract deadline 2026-05-19, fill=paramount."
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Pioneer Assembly — Indianapolis Plant Expansion",
"date": "2026-04-30",
"contract": {
"deadline": "2026-05-26",
"budget_total_usd": 220000,
"budget_per_hour_max": 30,
"local_bonus_per_hour": 5,
"local_bonus_radius_mi": 60,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-003",
"name": "Sam Torres",
"tenure_months": 4,
"role": "junior"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:30",
"role": "Assembler",
"count": 6,
"city": "Indianapolis",
"state": "IN",
"shift_start": "07:30 AM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "recurring",
"at": "09:30",
"role": "Quality Tech",
"count": 2,
"city": "Indianapolis",
"state": "IN",
"shift_start": "09:30 AM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "expansion",
"at": "11:00",
"role": "Machine Operator",
"count": 5,
"city": "Indianapolis",
"state": "IN",
"shift_start": "11:00 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "emergency",
"at": "14:00",
"role": "Machine Operator",
"count": 3,
"deadline": "16:00",
"city": "Indianapolis",
"state": "IN",
"shift_start": "14:00 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "misplacement",
"at": "16:00",
"role": "Assembler",
"count": 1,
"replaces_event": "07:30",
"city": "Indianapolis",
"state": "IN",
"shift_start": "16:00 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-26, fill=paramount."
}
]
}

View File

@ -0,0 +1,61 @@
{
"client": "Midway Distribution — Joliet DC Ramp",
"date": "2026-04-29",
"contract": {
"deadline": "2026-05-12",
"budget_total_usd": 120000,
"budget_per_hour_max": 28,
"local_bonus_per_hour": 3,
"local_bonus_radius_mi": 50,
"fill_requirement": "preferred"
},
"staffer": {
"id": "S-003",
"name": "Sam Torres",
"tenure_months": 4,
"role": "junior"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Warehouse Associate",
"count": 5,
"city": "Joliet",
"state": "IL",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "recurring",
"at": "10:00",
"role": "Forklift Operator",
"count": 3,
"city": "Joliet",
"state": "IL",
"shift_start": "10:00 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "expansion",
"at": "12:30",
"role": "Picker",
"count": 4,
"city": "Joliet",
"state": "IL",
"shift_start": "12:30 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "misplacement",
"at": "15:00",
"role": "Forklift Operator",
"count": 1,
"replaces_event": "10:00",
"city": "Joliet",
"state": "IL",
"shift_start": "15:00 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-12, fill=preferred."
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Riverline Logistics — Nashville Downtown Build-Out",
"date": "2026-04-28",
"contract": {
"deadline": "2026-05-19",
"budget_total_usd": 180000,
"budget_per_hour_max": 32,
"local_bonus_per_hour": 4,
"local_bonus_radius_mi": 75,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-003",
"name": "Sam Torres",
"tenure_months": 4,
"role": "junior"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Welder",
"count": 4,
"city": "Nashville",
"state": "TN",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "expansion",
"at": "08:30",
"role": "Packaging Operator",
"count": 6,
"city": "Nashville",
"state": "TN",
"shift_start": "08:30 AM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "baseline_fill",
"at": "09:00",
"role": "Shipping Clerk",
"count": 2,
"city": "Nashville",
"state": "TN",
"shift_start": "09:00 AM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "emergency",
"at": "13:00",
"role": "Welder",
"count": 2,
"deadline": "15:00",
"city": "Nashville",
"state": "TN",
"shift_start": "13:00 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "misplacement",
"at": "15:30",
"role": "Packaging Operator",
"count": 1,
"replaces_event": "08:30",
"city": "Nashville",
"state": "TN",
"shift_start": "15:30 PM",
"scenario_note": "Staffed by Sam Torres (junior, 4mo). Contract deadline 2026-05-19, fill=paramount."
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Pioneer Assembly — Indianapolis Plant Expansion",
"date": "2026-05-03",
"contract": {
"deadline": "2026-05-26",
"budget_total_usd": 220000,
"budget_per_hour_max": 30,
"local_bonus_per_hour": 5,
"local_bonus_radius_mi": 60,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-004",
"name": "Alex Rivera",
"tenure_months": 1,
"role": "trainee"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:30",
"role": "Assembler",
"count": 6,
"city": "Indianapolis",
"state": "IN",
"shift_start": "07:30 AM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "recurring",
"at": "09:30",
"role": "Quality Tech",
"count": 2,
"city": "Indianapolis",
"state": "IN",
"shift_start": "09:30 AM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "expansion",
"at": "11:00",
"role": "Machine Operator",
"count": 5,
"city": "Indianapolis",
"state": "IN",
"shift_start": "11:00 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "emergency",
"at": "14:00",
"role": "Machine Operator",
"count": 3,
"deadline": "16:00",
"city": "Indianapolis",
"state": "IN",
"shift_start": "14:00 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-26, fill=paramount."
},
{
"kind": "misplacement",
"at": "16:00",
"role": "Assembler",
"count": 1,
"replaces_event": "07:30",
"city": "Indianapolis",
"state": "IN",
"shift_start": "16:00 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-26, fill=paramount."
}
]
}

View File

@ -0,0 +1,61 @@
{
"client": "Midway Distribution — Joliet DC Ramp",
"date": "2026-05-02",
"contract": {
"deadline": "2026-05-12",
"budget_total_usd": 120000,
"budget_per_hour_max": 28,
"local_bonus_per_hour": 3,
"local_bonus_radius_mi": 50,
"fill_requirement": "preferred"
},
"staffer": {
"id": "S-004",
"name": "Alex Rivera",
"tenure_months": 1,
"role": "trainee"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Warehouse Associate",
"count": 5,
"city": "Joliet",
"state": "IL",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "recurring",
"at": "10:00",
"role": "Forklift Operator",
"count": 3,
"city": "Joliet",
"state": "IL",
"shift_start": "10:00 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "expansion",
"at": "12:30",
"role": "Picker",
"count": 4,
"city": "Joliet",
"state": "IL",
"shift_start": "12:30 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-12, fill=preferred."
},
{
"kind": "misplacement",
"at": "15:00",
"role": "Forklift Operator",
"count": 1,
"replaces_event": "10:00",
"city": "Joliet",
"state": "IL",
"shift_start": "15:00 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-12, fill=preferred."
}
]
}

View File

@ -0,0 +1,72 @@
{
"client": "Riverline Logistics — Nashville Downtown Build-Out",
"date": "2026-05-01",
"contract": {
"deadline": "2026-05-19",
"budget_total_usd": 180000,
"budget_per_hour_max": 32,
"local_bonus_per_hour": 4,
"local_bonus_radius_mi": 75,
"fill_requirement": "paramount"
},
"staffer": {
"id": "S-004",
"name": "Alex Rivera",
"tenure_months": 1,
"role": "trainee"
},
"events": [
{
"kind": "baseline_fill",
"at": "07:00",
"role": "Welder",
"count": 4,
"city": "Nashville",
"state": "TN",
"shift_start": "07:00 AM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "expansion",
"at": "08:30",
"role": "Packaging Operator",
"count": 6,
"city": "Nashville",
"state": "TN",
"shift_start": "08:30 AM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "baseline_fill",
"at": "09:00",
"role": "Shipping Clerk",
"count": 2,
"city": "Nashville",
"state": "TN",
"shift_start": "09:00 AM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "emergency",
"at": "13:00",
"role": "Welder",
"count": 2,
"deadline": "15:00",
"city": "Nashville",
"state": "TN",
"shift_start": "13:00 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-19, fill=paramount."
},
{
"kind": "misplacement",
"at": "15:30",
"role": "Packaging Operator",
"count": 1,
"replaces_event": "08:30",
"city": "Nashville",
"state": "TN",
"shift_start": "15:30 PM",
"scenario_note": "Staffed by Alex Rivera (trainee, 1mo). Contract deadline 2026-05-19, fill=paramount."
}
]
}

View File

@ -0,0 +1,77 @@
{
"count": 12,
"scenarios": [
{
"file": "S-001_nashville_downtown.json",
"staffer": "Maria Chen",
"contract": "nashville_downtown",
"client": "Riverline Logistics — Nashville Downtown Build-Out"
},
{
"file": "S-001_joliet_warehouse.json",
"staffer": "Maria Chen",
"contract": "joliet_warehouse",
"client": "Midway Distribution — Joliet DC Ramp"
},
{
"file": "S-001_indianapolis_assembly.json",
"staffer": "Maria Chen",
"contract": "indianapolis_assembly",
"client": "Pioneer Assembly — Indianapolis Plant Expansion"
},
{
"file": "S-002_nashville_downtown.json",
"staffer": "James Park",
"contract": "nashville_downtown",
"client": "Riverline Logistics — Nashville Downtown Build-Out"
},
{
"file": "S-002_joliet_warehouse.json",
"staffer": "James Park",
"contract": "joliet_warehouse",
"client": "Midway Distribution — Joliet DC Ramp"
},
{
"file": "S-002_indianapolis_assembly.json",
"staffer": "James Park",
"contract": "indianapolis_assembly",
"client": "Pioneer Assembly — Indianapolis Plant Expansion"
},
{
"file": "S-003_nashville_downtown.json",
"staffer": "Sam Torres",
"contract": "nashville_downtown",
"client": "Riverline Logistics — Nashville Downtown Build-Out"
},
{
"file": "S-003_joliet_warehouse.json",
"staffer": "Sam Torres",
"contract": "joliet_warehouse",
"client": "Midway Distribution — Joliet DC Ramp"
},
{
"file": "S-003_indianapolis_assembly.json",
"staffer": "Sam Torres",
"contract": "indianapolis_assembly",
"client": "Pioneer Assembly — Indianapolis Plant Expansion"
},
{
"file": "S-004_nashville_downtown.json",
"staffer": "Alex Rivera",
"contract": "nashville_downtown",
"client": "Riverline Logistics — Nashville Downtown Build-Out"
},
{
"file": "S-004_joliet_warehouse.json",
"staffer": "Alex Rivera",
"contract": "joliet_warehouse",
"client": "Midway Distribution — Joliet DC Ramp"
},
{
"file": "S-004_indianapolis_assembly.json",
"staffer": "Alex Rivera",
"contract": "indianapolis_assembly",
"client": "Pioneer Assembly — Indianapolis Plant Expansion"
}
]
}