Skip to content

Foundation + M0 Headless Service Lab (stops at M0 gate) - #1

Open
HSpector1 wants to merge 8 commits into
mainfrom
foundation/m0-headless-service-lab
Open

Foundation + M0 Headless Service Lab (stops at M0 gate)#1
HSpector1 wants to merge 8 commits into
mainfrom
foundation/m0-headless-service-lab

Conversation

@HSpector1

Copy link
Copy Markdown
Owner

M0 Headless Service Lab — foundation

Establishes the repository as the project's source of truth, folds in the accepted review findings, and builds the M0 Headless Service Lab. Stops at the M0 gate. Do not merge as "M1 authorized" — this closes only the technical half of M0; the fun/comprehension/replay half needs owner-run human playtests (see below).

What's here

  • Docs (source of truth): the v1 charter preserved immutably in docs/archive/2026-07-28/; an active MASTER-PLAN.md change-record; commercial hypothesis + go-to-market + comparables + Early-Access decision; honest EFFORT-AND-SCOPE (through-M3 = first-commercial cut; full ceiling is multi-year); a risk register with human/commercial risks (burnout, founder deadlock, funding, motivation, commercial indifference); determinism contract + 4 ADRs; fantasy-continuity resolution + deferred proof gate; playtest sourcing/script/consent; asset provenance + quarantine.
  • M0 simulation (src/RestaurantSim.Core): deterministic, integer-only, seeded RNG streams, no wall clock. Demand→choice→seating→kitchen→FOH→satisfaction→economy→causal autopsy→forecast→checksum. 3 segments, 12 recipes, 8 employees, 3 markets, 9 named strategies. CLI decision loop + distribution/determinism harness.
  • Tests: 74 passing (invariants, determinism incl. no-float reflection + no-wall-clock/System.Random scans, golden checksums, balance properties).

Evidence (in reports/, 200 seeds/cell)

  • Determinism: same seed ⇒ identical checksum across the matrix. PASS.
  • No dominant strategy: 2 of 3 distinct market winners (lunch → Focused Value; enthusiast → Premium Craft; social contested); every deliberately-bad strategy loses and is legibly diagnosed.
  • Honest finding: in a single service with no repeat visits, throughput dominates and quality has limited economic teeth — the key signal for M1 (repeat visits/reputation).

Scope audit

Clean. Nothing from the M0 non-goals list was built; asset packages quarantined and not committed.

Gate recommendation (reports/m0/M0-GATE-RECOMMENDATION.md)

Conditional-Pass (technical M0 proven) · Defer the Continue/Rewrite/Abandon decision to the owners pending an independent review + five uncoached human playtests. M1 is not begun and not authorized.

🤖 Generated with Claude Code

claude added 8 commits July 28, 2026 20:25
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…docs

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sset decisions

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…autopsy, revise)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ty tests (74)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@HSpector1

Copy link
Copy Markdown
Owner Author

Independent M0 Audit — PR #1

A. Review identity

  • Reviewer role: Independent Reviewer (did not design or build M0).
  • Repository: HSpector1/Restaurant · PR: Foundation + M0 Headless Service Lab (stops at M0 gate) #1 foundation/m0-headless-service-lab.
  • Commit reviewed: beb928965d45db203e403c46c37d24e4ddd2e461.
  • Method: fresh clone from GitHub (not the builder's working dir); 9 independent verification tracks run on isolated copies, each executing real programs and reporting actual output. The PR branch was never modified.
  • Environments: darwin / arm64 / .NET SDK 8.0.423, Debug and Release. Cross-OS not available → cross-OS determinism remains unverified (see K/F).
  • Date: 2026-07-28.

B. Executive verdict

  • Technical verdict: the foundation is sound and largely truthful — determinism, accounting integrity, RNG stream isolation, forecast immutability, scope discipline, and repo hygiene are all independently confirmed. But three claims are materially overstated: the causal autopsy misattributes the bottleneck in a boundary band, "no dominant strategy" is refuted by a found dominant configuration, and the forecast is systematically biased high (its confidence band contained 0 of 5 actual outcomes).
  • No Blockers. 3 High, 5 Medium, 12 Low, 20 Note.
  • Recommended action: Conditional-Pass / Defer (details in N).
  • Merge: merge only after the bounded correction pass in section M. M1 remains unauthorized regardless.

C. Claims table

Builder claim Confirmed Refined Refuted Unverified Evidence
Builds from a clean clone fresh clone → dotnet build -c Release = 0 warnings/0 errors
74 tests pass (count) 74 pass, 0 skipped, stable over 2 runs; note: ~20 distinct methods, inflated to 74 by two [Theory] 9×3 matrices
~2,300 lines of C# tracked source is 2,026 lines; higher count included generated obj/*.cs
Engine-independent authoritative core Core has no CLI/engine dependency; renderer/read-model owns no truth
Integer/fixed-point numerics, no float (CLI) zero float/double/decimal in Core; CLI price parse uses double (Medium NUM-2)
Named deterministic RNG streams / isolation perturbation test: +2 draws in one stream left all others byte-identical
Immutable forecasts (calibration) byte-identical before/after run, no RNG; but miscalibrated (High F1)
FNV-1a state checksums (scope) canonical, order-independent; covers economic aggregates only (Low DET-3)
No dominant strategy swept config beats all 9 named strategies in all 3 markets (High BAL-1)
Causal post-service report correct in clear cases; wrong constraint in a boundary band (High AUTOPSY-1)
No scope leak (engine/pathfinding/inventory/…) zero non-goal terms in src/; no binaries committed
Same seed → same result (cross-OS) identical checksums same-OS Debug+Release; cross-OS unverified
Conditional-Pass / Defer recommendation I concur (see N)

D. Blocking findings

None. Nothing makes the M0 lab untrustworthy as a deterministic, in-scope, reconciling simulation; nothing is fabricated; determinism holds; the build and tests are honest.

E. Non-blocking findings

High

H1 — Causal autopsy misattributes the bottleneck in a boundary band (AUTOPSY-1).
DiagnoseBottleneck (Simulator.cs:533-540) compares seatPressure = lostCap*100 (a lost-party count) against stationPressure = (util-6000) + peakQueue*100 (a utilization+queue proxel) via Math.Max. These scores are not on commensurable scales. Sweeping seats in an all-grill lunch (seed 12345): at seats=19 the report correctly says "Seating/capacity bottleneck"; at seats=20 the grill crosses 90% and stationPressure=4559 overrides seatPressure=4300, flipping the verdict to "Kitchen bottleneck at the Grill station … add grill capacity / move dishes off the menu" — while 43 parties were turned away at the door for lack of a seat vs only 15 lost to wait. Across seeds×seats, 12/24 cases blamed the kitchen while LostToCapacity strictly exceeded LostToWait. The advised action would not recover the dominant loss. This is the specific adversarial case (busiest-utilization station ≠ true cause). Why it matters: the autopsy is the M0 payoff — the player reads it and re-plans; a wrong action steers the revise-and-rerun loop, the exact failure the Clarity pillar promises to prevent. Required correction: score bottlenecks in commensurable lost-contribution units, or gate stationPressure so it cannot outrank a strictly larger door-loss; add a test that a run with LostToCapacity > LostToWait and a ≥88% station is not reported as a kitchen bottleneck.

H2 — "No dominant strategy" is overstated; a dominant configuration exists (BAL-1).
The harness compares only 9 hand-authored plans and concludes "no strategy wins every market → no dominant strategy." An independent random parameter sweep found a reasonable, un-exotic plan that beats all 9 named strategies in all 3 markets at 300 seeds: menu = Ribeye @ $52.65 + Veggie Bowl @ $16.65 + House Salad @ $6.97 + Ice Cream @ $6.75, grill-heavy crew, 58 seats. Median contribution: lunch $325 vs named-best $304; social $2,202 vs $507; enthusiast $2,014 vs $1,013. In an independent 3,000-plan run, 2/3,000 dominated all three markets and 26/3,000 dominated social alone. This is the value-volume chassis + high-margin premium anchor archetype the named set never tests, and it is the throughput-dominance weakness (F1/BAL-3) manifesting as an actual dominant strategy — the master plan's #1 kill risk. Required correction: re-scope the claim to "no single named strategy is best across all markets (2/3 distinct winners)"; add the missing archetype and/or an automated sweep to the harness so the dominance claim is tested against the space, not 9 points in it. Do not present "no dominant strategy" as an established M0 property.

H3 — Forecast is systematically biased high; its confidence band almost never contains the outcome (F1).
For the "Focused Value" preset the forecast is fixed at contribution $1,213.75 with a stated 77% band [$845.79 .. $1,581.71]. Actual contribution across 5 seeds: $454.30, $220.05, $46.30, $555.95, −$78.40 — 0 of 5 fall inside the band (all below it). Covers forecast 135 vs actual 93. The builder's own committed reports/m0/example-forecast-vs-actual.txt shows the same shape (forecast $1,980.52, band low $1,330.29, actual $546.50). Why it matters: the forecast is the planning signal the M0 loop depends on ("see forecast + uncertainty, commit, read autopsy"); a band that catches ~0% of outcomes will mislead a playtester on every run, contaminating the "can the player form a plan and be fairly informed?" judgment M0 exists to gate. The code comment "gaps expected and informative" understates this. Required correction: recalibrate the forecast (remove the systematic optimism in expectedCovers/checkPerCover — it does not model walkouts, comps, holding loss, or FOH delay) and repair the band so its stated confidence is empirically met, OR relabel it honestly ("optimistic ceiling estimate, not a calibrated interval") and disclose the bias. Add a harness metric for band-coverage vs stated confidence. Fix or disclose before human playtests.

Medium

  • M1 (AUTOPSY-2): HighestPressureStation is hardwired to the busiest-utilization station and is emitted even when the diagnosed cause is seating or weak demand — a descriptor mislabeled as causal. Rename to BusiestStation or null it when the cause is non-station.
  • M2 (G-F1): No behavioral test asserts FIFO service ordering or a correct labor value. FIFO→LIFO and zero-labor mutations were caught only by the opaque golden checksums, not by any invariant. Add direct behavioral assertions.
  • M3 (G-F2): The golden-checksum tests are self-referential (expected value = whatever ComputeChecksum currently emits; no independent oracle). Five of seven injected bugs were caught primarily/only by goldens. Document goldens as stability/regression guards, not correctness proofs, and give each economically meaningful invariant its own behavioral assertion.
  • M4 (NUM-2): Cli/Program.cs:128/137 parses prices with double.Parse(...) * 100long, which loses a cent on ~40% of common inputs (0.29→28¢, 19.99→1998¢) and uses no InvariantCulture (locale-dependent). PriceCents is fully authoritative. Only reachable via interactive CLI price entry (the committed fixtures/harness never hit it), but it is the last float on an authoritative-value path. Parse to integer cents without floating point.
  • M5 (I-F2): Even within the named set, "no dominance" is a weak binary threshold (distinctWinners == 1): Focused Value posts a positive median in all three markets and wins 2/3 — a soft-dominance signal. Tighten the claim and consider a stronger metric.

Low (12) and Note (20)

Selected: DET-3 checksum covers economic aggregates only (excludes forecast + diagnostic fields) — state the scope so M1 doesn't read "golden stable" as "whole result unchanged". DET-5 Segment(id) uses positional indexing Segments[(int)id] (unlike id-matched Recipe/Employee); reversing Segments silently returns wrong data instead of throwing — a latent world-model trap, add a construction-time Segments[i].Id == (SegmentId)i assertion. G-F4 the no-float reflection guard scans only instance fields, so a static double or a double property slips through (verified: not caught) — scan static + properties. G-F5 RngIsolationTests.Entity_streams_are_independent… actually only tests reproducibility, not independence (it passed under the key-collapse mutation); the sibling test is what caught it — rename or strengthen. REV-1 (my own): docs are internally inconsistent on cross-OS determinism — CURRENT-STATE.md correctly marks it an OPEN item, but DETERMINISM-CONTRACT.md's headline rule ("byte-identical end state on any machine, any OS, any run") and ADR-002 ("the FNV-1a checksum is stable across CPUs and OSes") assert it as verified fact. Hedge these to "designed/expected to be" pending an actual two-OS run. Full Low/Note list retained in the audit record.

F. Independent experiments (actual results)

  1. Clean clone beb9289; main = base commit only. Release build: 0 warnings, 0 errors.
  2. dotnet test -c Release74 pass, 0 skipped, stable across two runs.
  3. Same-seed repeat → identical checksum 0xF07AA46F729A0A8F, contribution 55595¢.
  4. Debug vs Release → identical checksum/contribution/covers.
  5. Reversed Recipes+Employees → checksum byte-identical (canonical, id-sorted). Reversed Segmentsdifferent (positional accessor, DET-5).
  6. RNG perturbation: +2 draws into the Execution stream → Arrivals/Party/Choice/Incident sequences byte-identical (hashes matched), while dish quality changed (non-vacuous). Stream isolation holds.
  7. Forecast immutability: Forecaster.Compute byte-identical before/after run; inserting a forecast between two seeded runs left the service checksum identical → forecaster consumes no RNG.
    8-13. Empty-menu / no-staff / zero-seats / extreme-price / service-close / reversed-order scenarios: no crashes; money reconciles; realistic extremes sane (overflow only at long.MaxValue/4 prices, unreachable).
  8. Controlled single-cause autopsy fixtures: correct in clear cases; misattributes in the boundary band (H1).
  9. Independent accounting reconciliation over 9×3×25: Contribution == Revenue − Ingredient − Labor − Overhead and per-dish sums exact — all pass.
  10. Harness reproduced at 300 seeds: 2/3 distinct named winners (matches builder).
  11. Dominance search: found a config dominating all 3 markets (H2).
  12. Mutation testing (7 bugs, then reverted): pay-failed-dishes → caught (reconciliation); zero-labor → caught weakly (goldens+balance only); drop-checksum-field → goldens only; FIFO→LIFO → goldens only; double instance field → caught (reflection); static double/property → NOT caught; complexity→0 → goldens+1 balance; RNG ignore-key → caught (isolation test).
  13. Scope-leak grep of src/ for 25 non-goal terms → only "Random" (the deterministic PRNG). No engine/renderer/inventory/save/etc.
  14. Docs-vs-code: mostly accurate; overclaims noted (H2, REV-1); asset CC0 hedged correctly.

G. Architecture assessment

  • Strengths: clean one-way pipeline (world + plan + seed → deterministic sim → read-model result → text/harness); Core has no engine/CLI dependency; integer-only numerics with an Int128-intermediate MulDivRound; per-(stream,entityKey) RNG derivation; canonical checksum. Right-sized for M0.
  • Weaknesses / debt: DiagnoseBottleneck heuristic is not lost-value-commensurable (H1); Segment(id) positional accessor is inconsistent with id-matched Recipe/Employee (DET-5); Forecaster is an independent estimator not derived from the sim, so it drifts from reality (H3); the no-float guard is instance-field-only (G-F4).
  • Suitability for M1 (if later authorized): good. The deterministic authoritative-state spine is the right foundation; the debt above is bounded and localized.

H. Simulation assessment

Menu/pricing/staffing/capacity produce genuinely different, context-dependent outcomes; throughput, staffing, pricing, capacity, failure, and revise-and-rerun all work and reconcile. Quality/causality are the weak spots: quality has no economic teeth beyond comped failures (confirmed), which enables the dominant archetype (H2); and causal attribution is correct in the clear cases but wrong in the boundary band (H1). Recovery/revision works mechanically; the loop's fairness depends on fixing the forecast (H3) and autopsy (H1).

I. Balance assessment

Reproduced: 2/3 distinct named winners; deliberately-bad strategies all lose and are (mostly) legibly diagnosed; no fixture leakage — the sim contains no branch on scenario.Id or strategy name, so balance is emergent, not rigged (independently confirmed). But "social contested" overstates: Focused Value soft-dominates (profitable in all three, wins 2/3), and a swept config hard-dominates all three (H2). Multiple rational named strategies genuinely exist; a single dominant strategy also exists. Both are true and both must be stated.

J. Scope assessment

Every hard non-goal: Absent in executable code (graphics, engine, pathfinding, spatial movement, inventory, supplier, spoilage, persistent save, database, campaign, competitor, city, manager, delegation, franchise, multi-restaurant, marketing, critic, audio, animation, Steam, telemetry, mods, asset imports). Deferred systems appear in docs only. Asset packages quarantined and not committed (no binaries tracked). Clean.

K. Test-quality assessment

The suite proves: ledger reconciliation, funnel non-negativity/ranges, comp-removes-failed-revenue, same-seed determinism, no-instance-float, no-wall-clock/System.Random, RNG key-distinctness, and 5 balance properties over 40 seeds. It does not prove: FIFO/queue ordering, a correct labor value, complexity-tax effect on breadth, forecast accuracy, or full-result checksum coverage — several behavioral bugs are caught only by self-referential golden hashes (M2/M3/G-F4/G-F5). Real, but leaning on goldens as the safety net.

L. Human-test readiness

The package can mechanically support a playtest: the CLI exposes inspect → plan → forecast → commit → autopsy → revise → run again, and the script/sourcing/consent docs are complete. But it is not yet fair to run: testers would be misinformed by the miscalibrated forecast (H3) on every run and misdirected by the boundary-band autopsy (H1). Fix or explicitly disclose both before the five-player gate, or the human evidence will be contaminated.

M. Required bounded correction pass (corrections only, no new features)

  1. H1: make bottleneck scoring lost-value-commensurable (or gate station-pressure below a larger door-loss); add the regression test.
  2. H3: recalibrate the forecast to the sim's real mean and repair the band — or relabel it "optimistic estimate" and disclose the bias; add band-coverage reporting.
  3. H2 / M5 / REV-1: correct the "no dominant strategy" wording to the true claim in CURRENT-STATE, M0-BALANCE-HYPOTHESES, and the gate report; fix the cross-OS determinism overclaim in DETERMINISM-CONTRACT and ADR-002.
  4. M1: rename/null HighestPressureStation when the cause is non-station.
  5. M4: parse CLI prices as integer cents (no double, InvariantCulture).
  6. M2/M3/G-F4: add a FIFO behavioral test and a labor-value test; extend the no-float guard to static fields + properties; label goldens as stability guards.

N. Final gate recommendation

Verdict: Conditional-Pass
Action: Defer

Conditional-Pass (not Pass-with-notes) because H1 and H3 are real behavior/correctness issues — not cosmetic — that must be corrected before the autopsy and forecast are trusted. Defer because the five-player human gate is outstanding and M1 is not authorized; do not read a technical pass as authorization to continue into M1.

O. Required owner decision

Howard & Aaron: authorize a single bounded M0 correction pass (fix the autopsy misattribution H1 + forecast calibration/disclosure H3 + correct the "no dominant strategy" and cross-OS claims) before running the five uncoached human playtests — versus proceeding to playtests now with those caveats explicitly disclosed to testers. Either path is legitimate; choosing "proceed with caveats" means accepting that the forecast and boundary-band autopsy may bias what testers report.


Merge recommendation: do not merge as-is; merge after the section-M corrections (they are corrections, not features). M1 remains unauthorized independent of the merge decision. The PR branch was not modified during this review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants