docs: add Hospitality context and launch tracker

This commit is contained in:
Samuel James 2026-08-27 06:36:14 -04:00
parent 2be85b112e
commit eab9613efa
2 changed files with 604 additions and 0 deletions

View File

@ -0,0 +1,243 @@
# SnS Hospitality Group — Codex Operating Context
This file is the durable context and working-memory entrypoint for Codex work in
`businesses/sns-hospitality-group/`. Read it before analyzing or changing anything
in this subtree. Treat it as a maintained navigation and decision aid, not as a
substitute for the source documents.
## Mission
Build SnS Hospitality Group LLC as a portfolio of repeatable mobile food and
beverage ventures. The active venture is **The Daily Pour**, a fleet concept for
drive-through coffee trailers in Northwest Indiana and Southern Michigan.
The operating doctrine is:
> Build one → learn → automate → reduce cost → prove profitability → replicate.
Sam's permanent role is capital allocation, strategy, systems, and final approval;
the business should not depend on him working shifts. Kiowa's intended lane is
locations, compliance, staffing, SOPs, and operational development. A Location
Manager is intended to operate each trailer.
## Current truth snapshot
Last reconciled by Codex: **2026-08-27**.
### Confirmed in repository documents
- SnS Hospitality Group LLC is documented as formed in Indiana on 2026-08-06.
- Sam confirms the operating agreement is signed and stored in Documenso.
- Guaranteed vested ownership is 85% Holdings / 15% Kiowa, with options that may
increase Kiowa's interest up to 25% under the executed agreement.
- The Daily Pour is the first and only active Hospitality venture.
- T00-DRIP is the prototype and remains pre-launch.
- The target is ten trailers, with later units funded primarily from retained cash.
- The latest physical concept uses an 8.5 × 26 ft enclosed trailer with a 7 ft
6 in interior height, drive-through service only, and no raw-food cooking line.
- Branding, recipes, market research, supplier research, financial projections,
compliance planning, and conceptual layouts exist.
### Not yet evidenced as complete
- Purchased trailer
- Executed lot lease or final operating location
- Health-department plan approval
- Final commissary determination
- DBA filing for The Daily Pour
- Mobile food permit, insurance, or employer registrations
- Final engineered electrical, plumbing, HVAC, and weight plans
- Funding approval or loan closing
- Hired Location Manager or opening staff
- Complete employee handbook and operating SOP library
- Production-ready fleet network configuration
Do not convert a plan, candidate, projection, checklist item, or generated mockup
into a statement that something has been purchased, approved, signed, deployed,
or proven.
## Venture relationship map
```text
SnS Network Solutions Holdings LLC
└── SnS Hospitality Group LLC
├── The Daily Pour
│ ├── T00-DRIP — prototype, pre-launch
│ └── T01T09 — proposed fleet
└── Other mobile concepts — future, not active Daily Pour units
Sam / Holdings ── capital, strategy, financial control, approvals
Kiowa ─────────── locations, compliance, staffing, SOPs, operations development
Location Manager ─ daily execution for one trailer
SNS Networking ── technology provider and security handoff, separate entity lane
```
Keep Hospitality operations and SNS Networking delivery responsibilities explicit.
Technology should support opening and operating the trailer; it must not become a
prerequisite unless required for payments, safety, compliance, or essential control.
## Authoritative-source order
Use the narrowest, newest, directly applicable source, while checking for conflicts:
1. Signed legal document or official agency/vendor record supplied by Sam
2. Current owner decision explicitly recorded in the repository
3. Latest dated, venture-specific specification or model
4. Current checklist or operational plan
5. High-level README or overview
6. Historical memory, old plan, generated mockup, or research note
For T00 physical design, start with:
- `coffee-trailers/T-00/version2.md`
- `coffee-trailers/T-00/docs/T-00-3D-layout-checklist.md`
- `coffee-trailers/T-00/docs/trailer-spec-sheet-for-designer.html`
- `coffee-trailers/T-00/trailer-candidate-midcity-us-cargo-8.5x26.md`
For finance, distinguish the original business plan from the newer models:
- `coffee-trailers/T-00/docs/daily-pour-sba-projection-assumptions.md`
- `coffee-trailers/T-00/docs/daily-pour-sba-projection.csv`
- `coffee-trailers/fleet-model-5yr-assumptions.md`
- `coffee-trailers/fleet-model-5yr-monthly.csv`
For compliance and people operations, start with:
- `docs/required-docs-and-compliance.md`
- `coffee-trailers/T-00/docs/health-dept-certification-checklist.html`
- `docs/handbook-tracker.html`
## Known conflicts that must not be silently resolved
| Topic | Conflicting repository positions | Required treatment |
|---|---|---|
| Ownership | Some drafts blur guaranteed 85/15 ownership with options up to 25% | State 85/15 as current; verify option mechanics against the executed agreement |
| Operating Agreement | Repository drafts conflict with the signed agreement | Documenso copy controls; archive conflicting drafts after reconciliation |
| Kiowa departure | Flat 50% FMV buyback vs. tiered 100/75/50/0 terms | Treat the executed agreement as controlling |
| Management | Holdings has sole day-to-day authority vs. Kiowa oversees operations | Clarify decision rights and escalation path |
| Trailer cost | ~$25K, $50K, and $60K financing concepts | Rebuild from current vendor-backed design quotes |
| Trailer size | Early 8 × 1416 ft concept vs. current 8.5 × 26 ft design | Use 8.5 × 26 ft unless Sam changes it |
| Equipment | One espresso line/older appliance list vs. two-station revised design | Use revised requirements; validate necessity and load |
| Warewashing | Two-compartment vs. three-compartment sink | Use three-compartment pending written health approval otherwise |
| Water heat | Propane tankless vs. all-electric | Current direction is all-electric |
| Electrical | 30A/3.5 kW generator vs. tentative 50A 120/240V | Require nameplate-load calculation before selection |
| Growth | Ten trailers in two years vs. approximately month 50 | Use the evidence-backed five-year model, not the early schedule |
| Profit | Flat 100 customers/day and ~49% net margin vs. ramped model | Use ramped cases; expose missing costs and sensitivity |
When a task touches one of these topics, report the conflict and its sources. Offer
resolution options, but do not choose legal, ownership, or capital terms for Sam.
## Decision gates
Prioritize work that advances the next physical-business gate. The current task is
receipt, review, correction, and approval of the $211 Fiverr blueprint package.
### Gate 1 — Feasible prototype
- Written health-department direction and plan-review path
- Commissary requirement determined
- Integrated layout, equipment, utilities, weight, and winterization concept
- Real vendor quotes and construction contingency
- Candidate location economics
### Gate 2 — Financeable unit
- Vendor-backed uses-of-funds schedule
- Conservative 24-month projection with sensitivity cases
- Owner contribution, working capital, debt terms, and reserve policy
- Legal ownership and tax-distribution terms reconciled
### Gate 3 — Ready to open
- Approved plans, permits, insurance, location agreement, and build
- Location Manager and staff hired and trained
- Minimum viable SOPs: food safety, open/close, cash/POS, inventory, cleaning,
incident response, equipment failure, and staffing coverage
- Essential POS, connectivity, security, and reporting operational
### Gate 4 — Ready to replicate
- At least 90 days of actual unit economics
- Repeat demand, throughput, labor, waste, maintenance, and downtime measured
- T00 profitable under an agreed definition
- Build book, training system, supplier terms, and launch checklist proven
Do not optimize Gate 4 systems while Gate 1 evidence is missing unless Sam explicitly
chooses that priority.
## Analysis method
For material decisions, keep a lightweight structured record:
1. **Decision:** What must be decided now?
2. **Confirmed evidence:** What do source documents or external authorities establish?
3. **Inference:** What reasonably follows, with confidence stated when useful?
4. **Assumptions:** What must be true for the proposal or model to work?
5. **Constraints:** Legal, health, physical, weight, power, cash, time, and staffing limits.
6. **Conflicts:** Which sources or requirements disagree?
7. **Evidence gaps:** What quote, approval, measurement, or owner choice retires the risk?
8. **Recommendation:** Smallest action that moves the current gate forward.
9. **Owner:** Sam, Kiowa, Location Manager, vendor, attorney, CPA, or agency.
Use `CONFIRMED`, `INFERRED`, and `AMBIGUOUS` where provenance matters. A polished
document is not evidence that its claims are true.
## Financial-analysis rules
- Separate revenue, gross margin, operating profit, debt service, taxes,
distributions, and retained growth cash.
- Show customer/day, average-ticket, COGS, labor, and build-cost sensitivities.
- Do not use the 15% COGS assumption as fact until weighted recipes and supplier
quotes support it.
- Include normal omitted costs: payroll service, accounting, marketing, training,
spoilage, cleaning, commissary, towing/storage, maintenance, permits, software,
snow closures, equipment reserves, and contingency.
- Treat Section 179, pass-through tax, certification, grants, credits, and loan
eligibility as CPA, attorney, agency, or lender validation items.
- Never describe projected profit as proven performance.
## Physical-design rules
- Plan review precedes irreversible buildout.
- Final equipment selection requires actual model numbers and nameplate loads.
- Track wet, dry, and loaded trailer weights plus axle, tongue, and side-to-side
distribution. Water weighs about 8.34 lb/gal before tank hardware.
- Preserve employee-door, restroom-door, service-window, equipment-service, and
central-aisle clearances.
- Keep potable, gray, black, electrical, battery, generator, HVAC, and food-safety
boundaries explicit.
- Prefer the smallest reliable operating system. Defer guest Wi-Fi, video calling,
AI detection, elaborate marketing automation, and fleet orchestration until the
prototype proves a need for them.
- Do not simplify away health, fire, electrical, structural, accessibility, payment,
privacy, or food-safety controls.
## Context maintenance
Update this file only when a durable fact, controlling decision, source hierarchy,
material conflict, or gate status changes. Do not turn it into a session transcript.
When updating:
- Add the date and source for material status changes.
- Retire resolved conflicts rather than preserving obsolete parallel truth.
- Keep private identifiers, account numbers, credentials, and personal contact data out.
- Link to the canonical source instead of duplicating long content.
- Preserve an explicit distinction between current truth and historical context.
## Upstream ideas adapted for Codex
This file applies selected ideas, rewritten for this workspace, from:
- Ponytail: understand the full problem, then choose the smallest sufficient action;
avoid speculative systems and unnecessary dependencies.
<https://github.com/DietrichGebert/ponytail>
- Graphify: model entities and relationships, retain provenance, and distinguish
extracted/confirmed facts from inference and ambiguity.
<https://github.com/Graphify-Labs/graphify>
- Business Analysis Skills: make assumptions, constraints, conflicts, stakeholders,
evidence gaps, traceability, and decision ownership visible.
<https://github.com/45ck/business-analysis-skills>
These are operating principles, not vendored code or installed plugins. Codex-native
workspace instructions and Sam's explicit directions control.

View File

@ -0,0 +1,361 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>T00-DRIP Launch Tracker</title>
<style>
:root {
--brown: #4b2e20;
--brown-2: #2c1a12;
--cream: #f7efe6;
--gold: #d4af37;
--pink: #e7b4b8;
--green: #2f6b4f;
--red: #9b2c2c;
--ink: #251d19;
--muted: #75665e;
--line: #ddcec2;
--white: #fffdf9;
}
* { box-sizing: border-box; }
body {
margin: 0;
color: var(--ink);
background: var(--cream);
font: 15px/1.45 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
header {
padding: 28px 20px 24px;
color: white;
background: linear-gradient(135deg, var(--brown-2), var(--brown));
border-bottom: 5px solid var(--gold);
}
header .wrap, main { max-width: 1180px; margin: auto; }
h1 { margin: 0 0 4px; font-family: Georgia, serif; font-size: clamp(26px, 4vw, 42px); }
header p { margin: 4px 0 0; color: #f5ddd7; }
main { padding: 20px; }
.summary {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
margin-bottom: 16px;
}
.card, .gate, .notice {
background: var(--white);
border: 1px solid var(--line);
border-radius: 10px;
box-shadow: 0 3px 10px rgb(44 26 18 / 6%);
}
.card { padding: 14px; }
.card strong { display: block; font-size: 26px; color: var(--brown); }
.card span { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; }
.notice { padding: 14px 16px; margin-bottom: 16px; border-left: 5px solid var(--gold); }
.notice strong { color: var(--brown); }
.progress { height: 12px; overflow: hidden; background: #e9ded5; border-radius: 999px; margin: 10px 0 18px; }
.progress > div { height: 100%; width: 0; background: linear-gradient(90deg, var(--pink), var(--gold)); transition: width .2s; }
.toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
button, select {
min-height: 38px;
padding: 8px 12px;
border: 1px solid var(--brown);
border-radius: 7px;
background: var(--white);
color: var(--brown);
font: inherit;
font-weight: 650;
}
button { cursor: pointer; }
button.primary { background: var(--brown); color: white; }
button:hover { filter: brightness(.96); }
.gate { margin: 0 0 14px; overflow: hidden; }
.gate-head {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: center;
padding: 14px 16px;
color: white;
background: var(--brown);
}
.gate-head h2 { margin: 0; font-family: Georgia, serif; font-size: 20px; }
.gate-head span { font-size: 12px; color: #f3ddd4; }
.tasks { width: 100%; border-collapse: collapse; }
th, td { padding: 11px 10px; border-bottom: 1px solid #eadfd7; text-align: left; vertical-align: top; }
th { color: var(--muted); background: #fbf6f0; font-size: 11px; text-transform: uppercase; letter-spacing: .07em; }
tr:last-child td { border-bottom: 0; }
tr.done .task-title { text-decoration: line-through; color: var(--muted); }
tr.blocked { background: #fff7f4; }
.check { width: 42px; text-align: center; }
input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--green); cursor: pointer; }
.task-title { display: block; font-weight: 700; }
.task-note { display: block; margin-top: 3px; color: var(--muted); font-size: 13px; }
.owner { white-space: nowrap; font-weight: 650; }
.status {
display: inline-block;
padding: 3px 8px;
border-radius: 999px;
font-size: 11px;
font-weight: 750;
white-space: nowrap;
}
.status.waiting { color: #6d4e00; background: #fff0bd; }
.status.next { color: #154b36; background: #dff4e9; }
.status.blocked { color: #7b1f1f; background: #f8dada; }
.status.later { color: #555; background: #ececec; }
.status.complete { color: #154b36; background: #dff4e9; }
.evidence { color: var(--muted); font-size: 12px; }
.hidden { display: none; }
footer { padding: 12px 20px 28px; color: var(--muted); text-align: center; font-size: 12px; }
@media (max-width: 800px) {
.summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tasks, .tasks tbody, .tasks tr, .tasks td { display: block; width: 100%; }
.tasks thead { display: none; }
.tasks tr { position: relative; padding: 10px 12px 10px 50px; border-bottom: 1px solid var(--line); }
.tasks td { padding: 4px 0; border: 0; }
.tasks td.check { position: absolute; left: 14px; top: 12px; width: 24px; }
}
@media print {
body { background: white; }
header { color: black; background: white; border-bottom: 2px solid black; }
header p { color: #333; }
.toolbar { display: none; }
.card, .gate, .notice { box-shadow: none; break-inside: avoid; }
.gate-head { color: black; background: #eee; }
.gate-head span { color: #333; }
}
</style>
</head>
<body>
<header>
<div class="wrap">
<h1>T00-DRIP Launch Tracker</h1>
<p>The Daily Pour · current gate: blueprint review and approval</p>
</div>
</header>
<main>
<section class="summary" aria-label="Progress summary">
<div class="card"><strong id="percent">0%</strong><span>Complete</span></div>
<div class="card"><strong id="done-count">0</strong><span>Completed</span></div>
<div class="card"><strong id="open-count">0</strong><span>Open</span></div>
<div class="card"><strong id="blocked-count">0</strong><span>Blocked / waiting</span></div>
</section>
<div class="progress" aria-label="Overall progress"><div id="progress-bar"></div></div>
<section class="notice">
<strong>Next move:</strong> receive the $211 Fiverr blueprint package, verify it against the current T00 requirements, and return one consolidated correction list before submission.
</section>
<div class="toolbar">
<select id="filter" aria-label="Filter tasks">
<option value="all">All tasks</option>
<option value="open">Open only</option>
<option value="blocked">Blocked / waiting</option>
<option value="complete">Complete</option>
</select>
<button class="primary" type="button" id="save">Save</button>
<button type="button" id="export">Export backup</button>
<button type="button" id="import">Import backup</button>
<button type="button" onclick="window.print()">Print / PDF</button>
<input class="hidden" id="import-file" type="file" accept="application/json">
</div>
<div id="gates"></div>
</main>
<footer>
Repository-backed working tracker. Browser state is stored locally; export a backup before changing computers.
</footer>
<script>
const storageKey = "daily-pour-t00-launch-tracker-v1";
const gates = [
{
title: "1. Company foundation",
purpose: "The entity and controlling agreement exist.",
tasks: [
["entity-formed", "SnS Hospitality Group LLC formed", "Sam", "complete", "Owner-confirmed and recorded in repository."],
["ein", "Federal EIN obtained", "Sam", "complete", "Store the official letter with legal originals."],
["oa", "Hospitality Operating Agreement executed", "Sam + Kiowa", "complete", "Authoritative signed copy is in Documenso."],
["dba", "File The Daily Pour assumed business name", "Sam", "next", "Confirm filing office and retain the accepted record."],
["bank", "Confirm operating-company bank account and controls", "Sam", "next", "Hospitality account only; Holdings remains asset-only and debt-free."]
]
},
{
title: "2. Blueprint package",
purpose: "Obtain a complete, internally consistent design before submission.",
tasks: [
["blueprint-receive", "Receive Fiverr blueprint package", "Designer", "waiting", "Paid $211. Obtain PDF plus editable/source files promised in the scope."],
["blueprint-shell", "Verify actual trailer shell and openings", "Sam", "blocked", "8.5×26 ft, 7 ft 6 in interior, ramp, V-nose, wheel wells, employee door and serving window."],
["blueprint-workflow", "Verify two-person production workflow", "Sam", "blocked", "Order/POS → production → finishing → drive-through handoff; preserve aisle and door clearances."],
["blueprint-equipment", "Reconcile every equipment item and quantity", "Sam", "blocked", "Use current requirements, not the older one-machine/propane design."],
["blueprint-plumbing", "Verify potable, gray, black and sink design", "Designer", "blocked", "Three-compartment sink, separate hand sink, restroom, accessible tanks, filtration and electric water heat."],
["blueprint-electric", "Verify electrical concept uses final load calculation", "Electrician / Designer", "blocked", "Do not approve panel, shore power, generator, inverter or battery sizing from guesses."],
["blueprint-weight", "Create loaded weight and balance schedule", "Designer / Fabricator", "blocked", "Include tanks, equipment, finishes, inventory, batteries, generator, axle and tongue loading."],
["blueprint-winter", "Verify South Bend winterization", "Designer / Plumber", "blocked", "Protect tanks, pumps, drains and vulnerable lines from freezing."],
["blueprint-fire", "Resolve ventilation and fire-protection notes", "Designer / Fire authority", "blocked", "Microwave and air fryer are reheating-only; no generic Type I hood assumption."],
["blueprint-corrections", "Send one consolidated correction list", "Sam", "blocked", "Avoid scattered messages and version confusion."],
["blueprint-freeze", "Approve submission version and archive superseded drafts", "Sam", "blocked", "One file must be clearly marked current."]
]
},
{
title: "3. Agency and professional approval",
purpose: "Secure written acceptance before irreversible construction.",
tasks: [
["health-contact", "Confirm plan-review process with St. Joseph County", "Kiowa", "next", "Request the current mobile-food plan-review packet and submission requirements."],
["commissary", "Obtain written commissary determination", "Kiowa", "next", "Confirm whether a self-contained unit still requires a licensed base or agreement."],
["sink-rule", "Confirm warewashing requirement", "Kiowa", "next", "Current design uses a three-compartment sink unless written approval permits otherwise."],
["food-cert-rule", "Confirm required food-protection credentials", "Kiowa", "next", "Determine certified-manager coverage and any staff food-handler requirements."],
["zoning", "Confirm location, zoning and mobile-vendor requirements", "Kiowa", "next", "Requirements may depend on the final operating parcel."],
["fire-review", "Confirm fire review requirements", "Kiowa", "later", "Use the final appliance, generator, battery and electrical design."],
["submit-plan", "Submit complete blueprint and equipment package", "Kiowa", "blocked", "Submit only after internal correction and professional calculations."],
["respond-comments", "Track and close every reviewer comment", "Kiowa + Designer", "blocked", "Record response, owner, date and revised sheet for each comment."],
["approval", "Receive written plan approval", "Kiowa", "blocked", "Approval evidence is the gate to irreversible buildout."]
]
},
{
title: "4. Site and unit economics",
purpose: "Prove the location and current design can support the business.",
tasks: [
["site-shortlist", "Create data-backed site shortlist", "Kiowa", "next", "Traffic, access, queue geometry, visibility, utilities, rent, competition and operating restrictions."],
["site-layout", "Validate drive-through circulation", "Kiowa", "blocked", "Confirm safe entry, queue, service-window alignment and exit."],
["site-utilities", "Document available site utilities", "Kiowa", "blocked", "Power, potable water, sewer/waste, cellular coverage, snow removal and overnight security."],
["site-economics", "Calculate break-even for the actual site", "Sam", "blocked", "Use actual rent, labor, utilities, debt, COGS and operating hours."],
["lease-review", "Review and execute lot agreement", "Sam + Attorney", "blocked", "Do not sign until design, use, utilities, signage, access and termination rights align."],
["backup-site", "Keep one qualified backup location", "Kiowa", "later", "Mobility only reduces risk when another viable site exists."]
]
},
{
title: "5. Funding and build readiness",
purpose: "Know the true cost and funding source before committing capital.",
tasks: [
["vendor-quotes", "Collect current trailer, buildout and equipment quotes", "Sam", "blocked", "Quotes must match the approved design and include tax, delivery and installation."],
["uses-funds", "Create final uses-of-funds schedule", "Sam", "blocked", "Include design, permits, contingency and opening working capital."],
["projection", "Update 24-month model from actual quotes", "Sam", "blocked", "Use ramped demand and sensitivity cases; do not assume 15% COGS without evidence."],
["funding-choice", "Select and approve operating-company funding", "Sam", "blocked", "No debt, guarantee or credit belongs in Holdings."],
["insurance-quotes", "Bind required insurance", "Kiowa + Sam", "blocked", "Match trailer, food service, employees, towing and location requirements."],
["build-contract", "Approve build contract and change-control terms", "Sam", "blocked", "Scope must reference the approved drawings and named equipment schedule."],
["purchase", "Authorize trailer and build purchases", "Sam", "blocked", "Only after approval, funding and contract gates are satisfied."]
]
},
{
title: "6. People and operating readiness",
purpose: "Open with qualified leadership and minimum viable controls.",
tasks: [
["manager-profile", "Finalize Location Manager role and scorecard", "Kiowa", "next", "Hire an operator who owns the unit; do not design a permanent shift for Sam."],
["cert-person", "Secure required certified food-protection coverage", "Kiowa", "next", "Credential requirement must match written county guidance."],
["barista-skill", "Recruit or train espresso-capable opening staff", "Kiowa", "next", "Use the recipe/spec books as the training standard."],
["employer-setup", "Complete payroll, withholding, unemployment and workers' compensation setup", "Sam + CPA", "blocked", "Complete before the first employee starts work."],
["handbook", "Complete and legally review the employee handbook", "Kiowa + Attorney", "next", "Prioritize food safety, health/safety, attendance, cash, discipline and acknowledgment."],
["sops", "Complete minimum opening SOP set", "Kiowa", "next", "Open/close, cleaning, temperature logs, recipes, inventory, POS/cash, incidents and equipment failure."],
["training", "Run opening-team training and readiness check", "Location Manager", "blocked", "Demonstrate workflow, sanitation, service, cash and emergency procedures."],
["permit-inspect", "Pass final inspections and receive operating permits", "Kiowa", "blocked", "Retain written approvals and renewal dates."],
["soft-open", "Run controlled soft opening", "Location Manager", "blocked", "Measure throughput, ticket, waste, labor and failure points before full launch."],
["launch", "Open T00-DRIP", "Location Manager", "blocked", "Sam monitors results; he does not become the daily operator."]
]
}
];
let state = JSON.parse(localStorage.getItem(storageKey) || "{}");
function currentStatus(task) {
return state[task[0]]?.status || task[3];
}
function render() {
const host = document.getElementById("gates");
const filter = document.getElementById("filter").value;
host.innerHTML = "";
for (const gate of gates) {
const section = document.createElement("section");
section.className = "gate";
section.innerHTML = `
<div class="gate-head"><div><h2>${gate.title}</h2><span>${gate.purpose}</span></div></div>
<table class="tasks"><thead><tr><th class="check">Done</th><th>Task</th><th>Owner</th><th>Status</th></tr></thead><tbody></tbody></table>`;
const tbody = section.querySelector("tbody");
let visible = 0;
for (const task of gate.tasks) {
const status = currentStatus(task);
const done = status === "complete";
const blocked = status === "blocked" || status === "waiting";
if ((filter === "open" && done) || (filter === "blocked" && !blocked) || (filter === "complete" && !done)) continue;
visible++;
const tr = document.createElement("tr");
tr.className = `${done ? "done" : ""} ${blocked ? "blocked" : ""}`;
tr.innerHTML = `
<td class="check"><input type="checkbox" data-id="${task[0]}" ${done ? "checked" : ""} aria-label="Complete ${task[1]}"></td>
<td><span class="task-title">${task[1]}</span><span class="task-note">${task[4]}</span></td>
<td class="owner">${task[2]}</td>
<td><span class="status ${status}">${status.replace("blocked", "blocked").replace("next", "next")}</span></td>`;
tbody.appendChild(tr);
}
if (visible) host.appendChild(section);
}
document.querySelectorAll('input[type="checkbox"][data-id]').forEach(box => {
box.addEventListener("change", event => {
const id = event.target.dataset.id;
const original = gates.flatMap(g => g.tasks).find(t => t[0] === id);
state[id] = { status: event.target.checked ? "complete" : original[3], updated: new Date().toISOString() };
save(false);
render();
});
});
updateSummary();
}
function updateSummary() {
const tasks = gates.flatMap(g => g.tasks);
const done = tasks.filter(t => currentStatus(t) === "complete").length;
const blocked = tasks.filter(t => ["blocked", "waiting"].includes(currentStatus(t))).length;
const percent = Math.round((done / tasks.length) * 100);
document.getElementById("percent").textContent = `${percent}%`;
document.getElementById("done-count").textContent = done;
document.getElementById("open-count").textContent = tasks.length - done;
document.getElementById("blocked-count").textContent = blocked;
document.getElementById("progress-bar").style.width = `${percent}%`;
}
function save(notify = true) {
localStorage.setItem(storageKey, JSON.stringify(state));
if (notify) alert("Progress saved in this browser.");
}
document.getElementById("filter").addEventListener("change", render);
document.getElementById("save").addEventListener("click", () => save(true));
document.getElementById("export").addEventListener("click", () => {
const blob = new Blob([JSON.stringify({ version: 1, exported: new Date().toISOString(), state }, null, 2)], { type: "application/json" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = `t00-launch-progress-${new Date().toISOString().slice(0, 10)}.json`;
link.click();
URL.revokeObjectURL(link.href);
});
document.getElementById("import").addEventListener("click", () => document.getElementById("import-file").click());
document.getElementById("import-file").addEventListener("change", async event => {
const file = event.target.files[0];
if (!file) return;
try {
const parsed = JSON.parse(await file.text());
if (!parsed.state || typeof parsed.state !== "object") throw new Error("Invalid tracker backup");
state = parsed.state;
save(false);
render();
} catch (error) {
alert(`Import failed: ${error.message}`);
}
event.target.value = "";
});
render();
</script>
</body>
</html>