# Bottleneck: model and provenance

An independently developed portfolio planning lab by Dustin Snellings, built with AI assistance. All ten sample jobs, their times, and the outage are fictional. No employer or Turblu data, processes, or code were used.

## Scope

A three-machine permutation flow shop: every job visits Cutting, Machining, then Inspection; every machine follows the same job order. All jobs are released at minute zero (08:00). One optional planned machine outage is known before any work starts. Operations are non-preemptive: a whole operation is moved after the outage if it would overlap it. The tool does not model an unexpected failure during a running operation.

Input: 2–10 unique jobs, three positive integer operation durations of 1–240 minutes each, and an integer due time of 1–2880 minutes after 08:00. Outage starts 0–480 minutes after 08:00 and lasts 0–240 minutes. The 16:00 marker is a visual reference, not a hard shift constraint; work can continue beyond it. No staffing, breaks, setup costs, material constraints, or alternative routes are represented.

## Mechanical search

For each next job, append it to a partial order and schedule each operation at the earliest time permitted by its preceding operation, the machine's previous operation, and the outage. Keep the best 120 prefixes at each depth, sorting by late-job count, total tardiness, makespan, then a stable order tie-break. Partial scores do not prove future optimality. At completion, compare with the unchanged original order, ensuring the selected score is never worse than that baseline. Fixed inputs give the same result; no randomness or language model is involved.

The result is **best found, not a proven global optimum**. This is a bounded beam search written for the restricted browser model, not Google OR-Tools or a general production scheduling solver. An independent result validator checks operation coverage, durations, precedence, machine overlaps, outage exclusion, machine ordering, and independently recomputed completion metrics.

The default synthetic example has 5 late jobs without the outage, 8 late jobs when the original order encounters a machining outage from 10:00 to 11:30, and 3 late jobs in the searched plan. These are simulation results, not achieved business savings. Reducing the number of late jobs can delay another job or increase its lateness; inspect the per-job comparison.

## Interface and privacy

D3 linear scales encode actual operation start and finish times. All three plan views use one common time scale. A time scrubber and optional playback show which operation is running on each machine. A table supplies exact completion times, and a job inspector explains stage times and direct outage delays. Imported CSVs replace the sample only after validation. Changing inputs invalidates previous search results. A module Web Worker performs the search off the UI thread, with a 15-second timeout and cancellation when the scenario changes. Exported CSVs contain the selected operations, not a claim that the plan is suitable for a real plant.

Sample-scenario links contain only the machine number and outage timing; sharing is disabled for custom job datasets. No job data is uploaded, stored persistently, or embedded in share URLs. There is no telemetry. Reloading restores the fictional sample.

## Verification

`npm run verify:bottleneck` checks reproducibility, scheduling invariants, outage boundaries, malformed inputs, baseline comparisons, worker execution, interactions, CSV import/export, and responsive rendering. Small cases are compared against exhaustive enumeration to check the search implementation within those cases; that does not prove optimality for larger cases.

## Planning workspace

The outage matrix evaluates 27 independent scenarios: all three machines, each with an outage starting at one of nine hourly points from 08:00 to 16:00. Every case uses the loaded job set and chosen outage duration. It reports original-order and best-found replanned results, not failure probabilities, simultaneous outages, or guaranteed resilience. Selecting a cell loads its exact inputs into the timeline. Changes to the jobs or outage duration invalidate the matrix.

Save up to six independent snapshots in tab memory. A separate worker recomputes comparisons using the same solver and validator. JSON export/import uses version 1 and includes only scenario names, jobs, and outage inputs; imported derived metrics are discarded. Files are capped at 100 KB and all scenarios must validate before replacement. No information is persisted automatically or sent to a server. Export before reloading if you want to retain snapshots.
