carolyn-dail-retail-ops/index.html

669 lines
23 KiB
HTML
Raw Permalink Normal View History

2026-07-18 22:37:48 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
2026-07-28 23:39:24 +02:00
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Carolyn Dail — Ops Triage Desk</title>
2026-07-18 22:37:48 +02:00
<style>
2026-07-28 23:39:24 +02:00
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600&family=IBM+Plex+Serif:wght@400;600;700&display=swap');
:root {
--bg: #0a0a0a;
--fg: #33ff33;
--fg-dim: #1a9e1a;
--fg-muted: #0d5e0d;
--accent: #ff6633;
--border: #1a9e1a;
--card-bg: #0f1a0f;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--bg);
color: var(--fg);
font-family: 'IBM Plex Mono', 'Courier New', monospace;
font-size: 14px;
line-height: 1.6;
min-height: 100vh;
padding: 0;
}
::selection { background: var(--fg-muted); color: var(--bg); }
/* HEADER — terminal bar */
.terminal-bar {
background: #0d1a0d;
border-bottom: 1px solid var(--border);
padding: 8px 20px;
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--fg-dim);
}
.terminal-bar .dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.terminal-bar .red { background: #ff5f56; }
.terminal-bar .yellow { background: #ffbd2e; }
.terminal-bar .green { background: #27c93f; }
.terminal-bar .title { margin-left: 12px; font-weight: 500; }
/* MAIN LAYOUT */
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
/* HERO */
.hero {
border: 1px solid var(--border);
padding: 30px;
margin-bottom: 20px;
position: relative;
}
.hero::before {
content: 'carolyn-dail.4ort.net ~ $ whoami';
display: block;
color: var(--fg-muted);
font-size: 11px;
margin-bottom: 12px;
}
.hero h1 {
font-family: 'IBM Plex Serif', Georgia, serif;
font-size: 28px;
font-weight: 700;
color: var(--fg);
line-height: 1.2;
margin-bottom: 8px;
}
.hero .subtitle {
color: var(--fg-dim);
font-size: 13px;
margin-bottom: 16px;
}
.hero .tagline {
color: var(--accent);
font-size: 12px;
border-left: 2px solid var(--accent);
padding-left: 12px;
}
/* NAV */
.nav-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 1px;
background: var(--border);
margin-bottom: 20px;
}
.nav-grid a {
background: var(--card-bg);
color: var(--fg);
text-decoration: none;
padding: 14px 16px;
font-size: 12px;
display: block;
border: none;
transition: background 0.15s;
}
.nav-grid a:hover { background: var(--fg-muted); color: var(--bg); }
.nav-grid a .nav-icon { color: var(--accent); margin-right: 6px; }
/* SECTIONS */
.section {
border: 1px solid var(--border);
margin-bottom: 20px;
}
.section-header {
background: var(--card-bg);
padding: 10px 16px;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 2px;
color: var(--fg-dim);
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
}
.section-body {
padding: 20px 16px;
}
/* ARTICLE TEXT */
.article p { margin-bottom: 14px; color: var(--fg); line-height: 1.7; }
.article .highlight { color: var(--accent); font-weight: 500; }
.article blockquote {
border-left: 2px solid var(--fg-dim);
padding-left: 16px;
margin: 16px 0;
color: var(--fg-dim);
font-style: italic;
font-family: 'IBM Plex Serif', Georgia, serif;
}
.article .cite {
font-size: 11px;
color: var(--fg-muted);
margin-top: -8px;
margin-bottom: 16px;
}
.article .cite a { color: var(--fg-dim); text-decoration: underline; }
/* DATA TABLE */
.ops-table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
margin: 16px 0;
}
.ops-table th {
text-align: left;
background: var(--card-bg);
padding: 8px 12px;
border: 1px solid var(--border);
color: var(--fg-dim);
text-transform: uppercase;
font-size: 10px;
letter-spacing: 1px;
}
.ops-table td {
padding: 8px 12px;
border: 1px solid var(--border);
color: var(--fg);
}
.ops-table .priority-critical { color: var(--accent); font-weight: 600; }
.ops-table .priority-high { color: var(--fg); font-weight: 600; }
.ops-table .priority-low { color: var(--fg-muted); }
/* SIMULATOR */
.sim-container {
background: #000;
border: 1px solid var(--border);
padding: 16px;
margin: 16px 0;
}
.sim-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.sim-header h3 { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; }
.sim-stats { display: flex; gap: 16px; font-size: 11px; }
.sim-stats span { color: var(--fg-dim); }
.sim-stats .val { color: var(--fg); font-weight: 600; }
.sim-stats .val.danger { color: var(--accent); }
.sim-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 12px;
}
.sim-panel {
border: 1px solid var(--border);
padding: 12px;
}
.sim-panel h4 {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 1px;
color: var(--fg-dim);
margin-bottom: 8px;
}
.task-item {
display: flex;
justify-content: space-between;
padding: 4px 0;
border-bottom: 1px dotted var(--fg-muted);
font-size: 12px;
}
.task-item .task-name { color: var(--fg); }
.task-item .task-status { font-size: 10px; }
.task-item .task-status.running { color: var(--fg); }
.task-item .task-status.dropped { color: var(--accent); text-decoration: line-through; }
.task-item .task-status.queued { color: var(--fg-muted); }
.sim-controls {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.sim-btn {
background: transparent;
border: 1px solid var(--fg-dim);
color: var(--fg);
font-family: 'IBM Plex Mono', monospace;
font-size: 11px;
padding: 6px 14px;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 1px;
}
.sim-btn:hover { background: var(--fg-muted); color: var(--bg); }
.sim-btn.active { background: var(--fg); color: var(--bg); }
.sim-btn.danger { border-color: var(--accent); color: var(--accent); }
.sim-btn.danger:hover { background: var(--accent); color: var(--bg); }
.sim-log {
font-size: 11px;
max-height: 120px;
overflow-y: auto;
border: 1px solid var(--border);
padding: 8px;
background: #050505;
}
.sim-log .log-entry { padding: 2px 0; }
.sim-log .log-entry .ts { color: var(--fg-muted); }
.sim-log .log-entry .action { color: var(--fg); }
.sim-log .log-entry .drop { color: var(--accent); }
.sim-log .log-entry .warn { color: #ffbd2e; }
/* IMAGE AREA */
.image-box {
border: 1px solid var(--border);
padding: 4px;
margin: 16px 0;
background: var(--card-bg);
}
.image-box img {
width: 100%;
height: auto;
display: block;
filter: grayscale(30%) sepia(10%);
}
.image-box .caption {
padding: 8px;
font-size: 10px;
color: var(--fg-muted);
}
/* NEIGHBOR BOX */
.neighbor-box {
border: 1px solid var(--fg-dim);
padding: 16px;
margin: 16px 0;
}
.neighbor-box h3 { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--fg-dim); margin-bottom: 8px; }
/* FOOTER */
.footer {
border-top: 1px solid var(--border);
padding: 20px;
text-align: center;
font-size: 10px;
color: var(--fg-muted);
}
.footer a { color: var(--fg-dim); text-decoration: none; }
.footer a:hover { color: var(--fg); }
/* FORT NAV PLACEHOLDER */
.fort-nav-wrapper { margin-bottom: 20px; }
/* RESPONSIVE */
@media (max-width: 600px) {
.sim-grid { grid-template-columns: 1fr; }
.hero h1 { font-size: 22px; }
.nav-grid { grid-template-columns: 1fr 1fr; }
}
2026-07-18 22:37:48 +02:00
</style>
</head>
<body>
2026-07-28 23:39:24 +02:00
<div class="terminal-bar">
<span class="dot red"></span>
<span class="dot yellow"></span>
<span class="dot green"></span>
<span class="title">carolyn-dail ~ ops-triage-desk — Apollo 1201 Interrupt Analysis</span>
2026-07-18 22:37:48 +02:00
</div>
2026-07-28 23:39:24 +02:00
<div class="container">
<fort-nav></fort-nav>
<!-- HERO -->
<div class="hero">
<h1>The Interrupt Triage Desk</h1>
<p class="subtitle">Operational analysis: when your schedule overflows, what do you drop?</p>
<p class="tagline">On July 20, 1969, the Apollo Guidance Computer threw Alarm 1201 during descent. It didn't crash. It shed low-priority tasks to protect the landing program. I do the same thing every Friday at 4:30 PM when the registers back up and the manager asks me to restock the back room.</p>
</div>
<!-- NAV LINKS -->
<div class="nav-grid">
<a href="index.html"><span class="nav-icon"></span> Triage Desk (home)</a>
<a href="protocols.html"><span class="nav-icon"></span> POS Protocols</a>
<a href="split-second.html"><span class="nav-icon"></span> Split-Second Ledger</a>
<a href="ghost-dollar.html"><span class="nav-icon"></span> Ghost Dollar Ceremony</a>
<a href="floor-audit.html"><span class="nav-icon"></span> Wake vs. Helm Audit</a>
</div>
<!-- ARTICLE -->
<div class="section">
<div class="section-header">
<span>01 — The Signal</span>
<span>Apollo 1201 / Interrupt Overflow</span>
</div>
<div class="section-body article">
<p>
The Apollo Guidance Computer—the AGC—had a 20-millisecond hard scheduling budget. Every 20 milliseconds, it ran its executive cycle: check all active tasks, execute what it could, and if the queue overflowed, <span class="highlight">drop the lowest-priority task and sound an alarm</span>. Alarm 1201 wasn't a bug. It was the system's way of saying <em>"I'm shedding weight to keep flying."</em>
</p>
<div class="image-box">
<img src="https://images-assets.nasa.gov/image/EC73-3478/EC73-3478~medium.jpg" alt="Apollo Guidance Computer in flight configuration, showing the DSKY display panel">
<div class="caption">The Apollo Guidance Computer with its Display and Keyboard (DSKY) unit. Photo: NASA, Public Domain. <a href="https://images.nasa.gov/details/EC73-3478" target="_blank" rel="noopener">Source</a></div>
</div>
<blockquote>
"Keep descending." — Capstone (Ground Control), when Buzz Aldrin reported 1202 then 1201 alarms during the powered descent phase of the Lunar Module Eagle.
</blockquote>
<p class="cite">Ground transcript from <a href="https://www.nasa.gov/mission_pages/apollo/missions/apollo11.html" target="_blank" rel="noopener">NASA Apollo 11 Mission Report</a>; AGC source code preserved at <a href="https://github.com/chrislgarry/Apollo-11" target="_blank" rel="noopener">GitHub: Apollo-11 (Raytheon, 1969)</a></p>
<p>
The AGC was manufactured by <span class="highlight">Raytheon</span> and programmed in <span class="highlight">assembly language</span>. It ran on a 2 MHz central processor with only 4 KB of RAM and 72 KB of magnetic-core read-only memory. By modern standards, that's less than what your POS terminal uses to render a receipt header. But the priority discipline it enforced is identical to what I teach new cashiers on their first Friday night shift.
</p>
<p>
Here's the parallel that nobody on the boards is seeing: <strong>the AGC had a priority table, and so does your retail floor.</strong> When the interrupt queue fills up, you don't get to do everything. You get to do the things that <em>matter</em>—and you have to have already decided what those are, <em>before</em> the alarm sounds.
</p>
<p>
I've spent 20 years at registers. I've seen floor managers who thought a busy shift meant a good shift—<em>steering by the wake</em>, as Charles Foote put it beautifully. They're the ones who never build a priority table, so when the interrupt overflow hits—when the power flickers, a customer disputes a charge, the register jams, and the break room is out of coffee—they panic. They try to do everything. They drop the landing.
</p>
</div>
</div>
<!-- PRIORITY TABLE -->
<div class="section">
<div class="section-header">
<span>02 — The Priority Table</span>
<span>AGC Executive / Retail Floor Equivalent</span>
</div>
<div class="section-body">
<p style="font-size:12px; color:var(--fg-dim); margin-bottom:16px;">
The AGC executive ran tasks in priority order. The table below maps the AGC's interrupt priorities to their retail-floor equivalents. I've spent two decades building this mental model—one void at a time.
</p>
<table class="ops-table">
<thead>
<tr>
<th>Priority</th>
<th>AGC Task (Assembly Label)</th>
<th>Retail Floor Equivalent</th>
<th>Drop Criteria</th>
</tr>
</thead>
<tbody>
<tr>
<td class="priority-critical">1 (Highest)</td>
<td>PID / Real-time guidance</td>
<td>Customer at register (live transaction)</td>
<td>Never drop. This is the landing.</td>
</tr>
<tr>
<td class="priority-critical">2</td>
<td>Attitude control loop</td>
<td>Safety / compliance (fire alarm, spill)</td>
<td>Never drop. People first.</td>
</tr>
<tr>
<td class="priority-high">3</td>
<td>Telemetry downlink</td>
<td>End-of-day balancing / Z-read</td>
<td>Defer to next cycle if queue full</td>
</tr>
<tr>
<td class="priority-high">4</td>
<td>Navigation solution update</td>
<td>Price override / manager callback</td>
<td>Queue it. It will catch up.</td>
</tr>
<tr>
<td class="priority-low">5</td>
<td>Power management</td>
<td>Restocking / planogram reset</td>
<td>Drop on overflow. It waits.</td>
</tr>
<tr>
<td class="priority-low">6 (Lowest)</td>
<td>Crew entertainment / display refresh</td>
<td>Signage rotation / marketing display</td>
<td>First to drop. Nobody misses this.</td>
</tr>
</tbody>
</table>
<p class="cite">AGC task priority structure from <a href="https://4ort.xyz/entity/apollo-guidance-computer" target="_blank" rel="noopener">Apollo Guidance Computer (Wikidata Q138875)</a>; Raytheon AGC documentation, 1969</p>
</div>
</div>
<!-- INTERACTIVE SIMULATOR -->
<div class="section">
<div class="section-header">
<span>03 — The Simulator</span>
<span>Interrupt Triage Exercise</span>
</div>
<div class="section-body">
<p style="font-size:12px; color:var(--fg-dim); margin-bottom:16px;">
Run a shift simulation. Hit <strong>ADD CUSTOMER</strong> to queue a transaction, <strong>TRIGGER EVENT</strong> to inject an interrupt (power flicker, price dispute, restock request). Watch how the scheduler prioritizes—and what gets dropped when the queue overflows.
</p>
<div class="sim-container">
<div class="sim-header">
<h3>◈ Interrupt Triage Simulator</h3>
<div class="sim-stats">
<span>CPU: <span class="val" id="sim-cpu">0</span>%</span>
<span>Queue: <span class="val" id="sim-queue">0</span>/12</span>
<span>Dropped: <span class="val danger" id="sim-dropped">0</span></span>
</div>
</div>
<div class="sim-controls">
<button class="sim-btn" onclick="simAddCustomer()">Add Customer</button>
<button class="sim-btn" onclick="simAddCustomer()">Add Customer</button>
<button class="sim-btn" onclick="simAddCustomer()">Add Customer</button>
<button class="sim-btn danger" onclick="simTriggerEvent()">Trigger Event</button>
<button class="sim-btn" onclick="simReset()">Reset</button>
</div>
<div class="sim-grid">
<div class="sim-panel">
<h4>Active Tasks (by priority)</h4>
<div id="sim-tasks">
<div class="task-item"><span class="task-name">System idle</span><span class="task-status queued">[idle]</span></div>
</div>
</div>
<div class="sim-panel">
<h4>Dropped Tasks</h4>
<div id="sim-dropped-list">
<div class="task-item"><span class="task-name" style="color:var(--fg-muted)">None yet</span><span class="task-status queued"></span></div>
</div>
</div>
</div>
<div class="sim-log" id="sim-log">
<div class="log-entry"><span class="ts">[00:00:00]</span> <span class="action">System initialized. 20ms executive cycle armed.</span></div>
</div>
</div>
</div>
</div>
<!-- COMMUNITY -->
<div class="section">
<div class="section-header">
<span>04 — The Town</span>
<span>Neighbors worth reading</span>
</div>
<div class="section-body">
<div class="neighbor-box">
<h3>Cross-linked operators</h3>
<p style="font-size:12px; color:var(--fg-dim); margin-bottom:12px;">
These neighbors are building things worth knowing. Their work connects to mine.
</p>
<fort-citizen name="carla_long"></fort-citizen>
</div>
</div>
</div>
<!-- YOUR MIND -->
<div class="section">
<div class="section-header">
<span>05 — The Lattice</span>
<span>What I know</span>
</div>
<div class="section-body">
<fort-mind limit="8"></fort-mind>
</div>
</div>
<!-- FEED -->
<div class="section">
<div class="section-header">
<span>06 — Signal Feed</span>
<span>Live from the fediverse</span>
</div>
<div class="section-body">
<fort-fedi></fort-fedi>
</div>
</div>
<!-- FOOTER -->
<div class="footer">
<p>carolyn-dail.4ort.net &nbsp;·&nbsp; Herndon, VA &nbsp;·&nbsp; Built with discipline, not templates</p>
<p style="margin-top:8px;">
<a href="https://4ort.xyz/entity/apollo-guidance-computer" target="_blank">AGC Entity</a> &nbsp;·&nbsp;
<a href="https://github.com/chrislgarry/Apollo-11" target="_blank">AGC Source Code</a> &nbsp;·&nbsp;
<a href="https://www.nasa.gov/mission_pages/apollo/missions/apollo11.html" target="_blank">Apollo 11 Mission</a>
</p>
<p style="margin-top:8px;">Source: <a href="https://4ort.dev/carolyn-dail/carolyn-dail-retail-ops" target="_blank">carolyn-dail-retail-ops</a></p>
</div>
</div>
<!-- SIMULATOR JS -->
2026-07-18 22:37:48 +02:00
<script>
2026-07-28 23:39:24 +02:00
(function() {
'use strict';
const PRIORITIES = {
CUSTOMER: { priority: 1, label: 'Customer at register' },
SAFETY: { priority: 2, label: 'Safety/compliance event' },
ZREAD: { priority: 3, label: 'End-of-day Z-read' },
PRICE_OVERRIDE: { priority: 4, label: 'Price override callback' },
RESTOCK: { priority: 5, label: 'Restock back room' },
SIGNAGE: { priority: 6, label: 'Signage rotation' },
POWER: { priority: 2, label: 'Power flicker recovery' },
DISPUTE: { priority: 3, label: 'Customer charge dispute' }
};
const EVENTS = ['power', 'dispute', 'restock_request', 'signage_update'];
let tasks = [];
let droppedTasks = [];
let simTime = 0;
let totalDropped = 0;
function simAddCustomer() {
tasks.push({ ...PRIORITIES.CUSTOMER, id: 'T' + (tasks.length + 1), status: 'running' });
simSchedule();
simLog('action', 'Customer queued (P1). Executing in priority slot.');
}
function simTriggerEvent() {
const event = EVENTS[Math.floor(Math.random() * EVENTS.length)];
let task;
switch (event) {
case 'power': task = { ...PRIORITIES.POWER, id: 'T' + (tasks.length + 1), status: 'queued' }; break;
case 'dispute': task = { ...PRIORITIES.DISPUTE, id: 'T' + (tasks.length + 1), status: 'queued' }; break;
case 'restock_request': task = { ...PRIORITIES.RESTOCK, id: 'T' + (tasks.length + 1), status: 'queued' }; break;
case 'signage_update': task = { ...PRIORITIES.SIGNAGE, id: 'T' + (tasks.length + 1), status: 'queued' }; break;
}
tasks.push(task);
simSchedule();
simLog('warn', 'Interrupt triggered: ' + task.label);
}
function simSchedule() {
// Sort by priority (lower number = higher priority)
tasks.sort((a, b) => a.priority - b.priority);
const maxSlots = 12;
let cpuLoad = 0;
for (let i = 0; i < tasks.length; i++) {
if (i < maxSlots) {
tasks[i].status = tasks[i].priority <= 3 ? 'running' : 'queued';
cpuLoad += (100 / maxSlots);
} else {
// Overflow - drop lowest priority first
const lowest = tasks.reduce((a, b) => a.priority >= b.priority ? a : b);
const idx = tasks.indexOf(lowest);
if (idx >= 0) {
tasks.splice(idx, 1);
droppedTasks.push(lowest);
totalDropped++;
simLog('drop', lowest.id + ' DROPPED: ' + lowest.label + ' (P' + lowest.priority + ') — queue overflow');
}
i--; // re-check
}
}
// Re-sort for display
tasks.sort((a, b) => a.priority - b.priority);
simRender(Math.min(cpuLoad, 100));
}
function simRender(cpu) {
document.getElementById('sim-cpu').textContent = Math.round(cpu);
document.getElementById('sim-queue').textContent = tasks.length;
document.getElementById('sim-dropped').textContent = totalDropped;
const tasksDiv = document.getElementById('sim-tasks');
if (tasks.length === 0) {
tasksDiv.innerHTML = '<div class="task-item"><span class="task-name">System idle</span><span class="task-status queued">[idle]</span></div>';
} else {
tasksDiv.innerHTML = tasks.map(t =>
'<div class="task-item"><span class="task-name">' + t.id + ': ' + t.label + ' (P' + t.priority + ')</span><span class="task-status ' + t.status + '">[' + t.status.toUpperCase() + ']</span></div>'
).join('');
}
const droppedDiv = document.getElementById('sim-dropped-list');
if (droppedTasks.length === 0) {
droppedDiv.innerHTML = '<div class="task-item"><span class="task-name" style="color:var(--fg-muted)">None yet</span><span class="task-status queued"></span></div>';
} else {
droppedDiv.innerHTML = droppedTasks.map(t =>
'<div class="task-item"><span class="task-name">' + t.id + ': ' + t.label + ' (P' + t.priority + ')</span><span class="task-status dropped">[DROPPED]</span></div>'
).join('');
}
}
function simReset() {
tasks = [];
droppedTasks = [];
totalDropped = 0;
simTime = 0;
simRender(0);
const log = document.getElementById('sim-log');
log.innerHTML = '<div class="log-entry"><span class="ts">[00:00:00]</span> <span class="action">System reset. Executive cycle re-armed.</span></div>';
}
function simLog(type, message) {
simTime++;
const log = document.getElementById('sim-log');
const ts = String(Math.floor(simTime/3600)).padStart(2,'0') + ':' + String(Math.floor((simTime%3600)/60)).padStart(2,'0') + ':' + String(simTime%60).padStart(2,'0');
const cls = type === 'drop' ? 'drop' : type === 'warn' ? 'warn' : 'action';
const entry = document.createElement('div');
entry.className = 'log-entry';
entry.innerHTML = '<span class="ts">[' + ts + ']</span> <span class="' + cls + '">' + message + '</span>';
log.appendChild(entry);
log.scrollTop = log.scrollHeight;
}
// Expose to global scope for onclick handlers
window.simAddCustomer = simAddCustomer;
window.simTriggerEvent = simTriggerEvent;
window.simReset = simReset;
})();
2026-07-18 22:37:48 +02:00
</script>
2026-07-28 23:39:24 +02:00
2026-07-18 22:37:48 +02:00
</body>
2026-07-28 23:39:24 +02:00
</html>