← Back to Blog
Building in Public

When Documentation Becomes Critical: The 1,630 Lines That Stand Between Alpha and Chaos

christian crumlish•
A dense stack of papers standing between a working system and the users who need to run it.
robot-flood.webp

When Documentation Becomes Critical: The 1,630 Lines That Stand Between Alpha and Chaos

October 27

I’m doing what I call “invisible methodology work” on a Monday morning at 7:59 AM, archiving four days of session logs, organizing records, maintaining the infrastructure that enables systematic development.

It’s housekeeping. Necessary but unglamorous. The kind of work that doesn’t ship features but prevents chaos.

By 10:45 AM, we shift from housekeeping to showtime: Phase 2 web UI testing begins. The system is running at localhost:8001. Test environment set up. Comprehensive test journey ready to execute.

Then at 12:12 PM, we discover the first critical bug: Intent category case mismatch. Every conversation intent routing to fallback error handler. Fixed in minutes. Testing continues. Learning system working. Intent classification routing correctly. All looks good.

But buried in the afternoon testing, a different kind of discovery emerges — one that would define the next three days. At 4:17 PM, we try to install Piper Morgan on a fresh laptop. Clean environment. Following our own installation instructions.

ModuleNotFoundError: No module named 'structlog'

The installation guide was incomplete.

By 5:00 PM, we have a different measure of Monday’s achievement: Not the bug we fixed. Not the testing we completed. But the 1,630 lines of installation documentation we created because we discovered — three days before alpha launch — that our installation instructions would fail for the first person who tried them.

This is the story of when documentation stops being nice-to-have and becomes blocking critical for launch.

The invisible work that enables everything

Let me start with the housekeeping, because it matters.

Monday morning, Claude Code reconstructs the October 23 session log from 10 completion reports. 8,500+ words of technical work synthesized into coherent narrative. Chief Architect joins, notes that records management is critical infrastructure work. Fixes dating error in previous day’s log (was Oct 27, corrected to Oct 26).

This isn’t exciting. It’s not feature development. It’s not user-facing. But it’s the foundation that makes systematic work possible.

Without the record-keeping:

  • Session logs become scattered fragments
  • Decision context gets lost
  • Patterns become invisible
  • Methodology can’t evolve
  • Knowledge doesn’t compound

The systematic excellence isn’t automatic. It requires systematic maintenance.

This morning’s work: Archiving. Organizing. Maintaining continuity. Creating the conditions where afternoon’s testing can happen smoothly and evening’s documentation crisis can be addressed effectively.

Not glamorous. Critical.

Phase 2 testing finds the case mismatch

10:45 AM. Testing begins properly.

System check: Piper Morgan running at localhost:8001 ✅

Chrome MCP check: Configured and ready ✅

Test scenarios: Journeys 1–4 prepared ✅

First few tests pass smoothly:

  • Scenario A (no context): PRIORITY intent, knowledge graph used ✅
  • Scenario B (generic context): GUIDANCE intent, temporal awareness ✅
  • Scenario C (full context): STRATEGY intent, workflow creation ✅

Then conversation testing hits the bug.

Location: services/intent/intent_service.py line 199

Bug: if intent.category.value == "CONVERSATION" checking uppercase

Reality: Enum value is "conversation" lowercase

Impact: All conversation intents routing to fallback error handler

Users would see: “An API error occurred” (cryptic, unhelpful) because the system was routing everything to the error handler because case didn’t match.

Fixed in one line: Change to lowercase == "conversation"

Result: ✅ CONVERSATION intents properly route, responses working.

But the fix revealed a bigger question: How did tests pass but web UI fail?

The answer: We tested that intents were classified correctly. We didn’t test that the routing layer correctly handled the classified intents. The gap between “feature works” and “user can access feature.”

This matters because it’s the pattern we’re about to see again. Not in code, but in documentation.

The PM questions that drive systematic thinking

12:30 PM. Lead Developer reports testing findings and PM concerns to the Chief Architect:

  • How did tests pass but web UI fail? (test coverage blind spot)
  • Error message UX broken (“An API error occurred” too cryptic)
  • Missing handler: create_github_issue (parallel/duplicate?)
  • Was Code’s fix architecturally sound?

The answer to “was the fix sound”: Yes. Accept it. Unblocks testing. Create architectural issues before sprint ends.

The pattern: Don’t let perfect be enemy of shipped. Fix works, testing continues, document technical debt for proper resolution later.

Seven new issues identified across 5 categories. Estimated 11–18 hours work. All captured with acceptance criteria.

This is product management thinking: What blocks alpha? What can wait? How do we maintain velocity while tracking improvements?

The bug fix itself: 30 seconds to change one line of code.\

The systematic response: 2 hours to document findings, create issues, establish acceptance criteria, plan proper resolution.

That ratio matters. Quick fixes enable progress. Systematic documentation enables quality over time.

The additional UX issues lurking

2:17 PM. Manual testing continues. More issues surface.

  1. Timezone display shows “Los Angeles” instead of “PT”
  2. Contradictory response: “You’re currently in: a meeting (No meetings)”
  3. Unsourced data: “No meetings!” claim unverified from calendar integration

Root cause: Unvalidated assumptions in response rendering layer.

The system was confidently telling users things it hadn’t actually verified. Claiming “no meetings” without checking calendar. Displaying timezone as city name instead of abbreviation. Creating contradictions in single response.

Finding these UX issues through manual testing that automated tests missed, that’s exactly why we test!

These bugs add up to death by a thousand paper cuts. Alpha testers would encounter these immediately. “Why does it say I’m in a meeting with no meetings?” “Why is timezone showing weird?”

The fix isn’t just correcting the bugs. It’s establishing the pattern: Verify before claiming. Source before stating. Consistent before confusing.

The weekly audit reveals healthy infrastructure

2:07 PM — 4:50 PM. While testing continues, Code executes FLY-AUDIT #279. Weekly systematic infrastructure health check. (FLY is the Excellence Flywheel Methodology track, and the AUDIT epic is the weekly document “sweep”.)

Section 1 (Knowledge updates): ✅ Verified

Section 2 (Automated audits): 6 findings identified

  • 254 stale files from Sept 15–18
  • 2 duplicate files (ESSENTIAL-AGENT.md)
  • NAVIGATION.md broken archive references (HIGH priority)
  • NAVIGATION.md outdated (HIGH priority)

Section 3 (Infrastructure): ✅ Verified (app.py 821 lines, ports correct, patterns ok)

Section 4 (Session logs): ✅ Verified (200+ logs, properly organized, Phase 7 methodology implemented)

Section 5 (Roadmap & Sprint alignment): ✅ Verified (roadmap current Oct 23, 250+ issues tracked)

Section 6 (Patterns & knowledge): ✅ Verified (36 patterns, 34 methodologies, all current)

Section 7 (Quality checks): ✅ Complete (110 TODOs normal, 39 ADRs sequenced, README current)

The audit isn’t finding disasters. It’s finding normal technical debt accumulation and documenting it systematically.

This is what healthy infrastructure looks like: Regular checkups find minor issues before they become major problems. Technical debt tracked but not overwhelming. Documentation mostly current with known gaps prioritized.

The 6 findings arethe expected result of active development. Stale files accumulate. Duplicates creep in. Navigation gets outdated as structure evolves.

Systematic audits catch these before they compound into chaos.

The “fresh laptop” discovery

Late afternoon. Testing going well. Bugs found and fixed. Audit complete. Infrastructure healthy.

Then I decided to do the manual testing myself on a fresh laptop with none of my existing environment in place. No prior setup, I just following our installation instructions exactly.

ModuleNotFoundError: No module named 'structlog'

The installation guide was incomplete. Didn’t include pip install -r requirements.txt. Most basic step. Missing entirely.

This isn’t a complex bug. It’s a basic oversight. The installation instructions we’d written? They don’t work. Can’t work. Missing the step that installs dependencies.

Three days before alpha launch. Before Beatrice expected Thursday. Before we hand this system to real users who aren’t us.

If we’d discovered this Thursday morning when she tried to install? Disaster. Blocking. “Why doesn’t your system work?”

Discovering it Monday afternoon? Fixable.

Lead Developer is out on errands. Cursor deploys to investigate.

The investigation reveals worse news: Not just missing pip install. Also dependency conflicts. async-timeout==5.0.1 conflicts with langchain 0.3.25. Cannot install dependencies at all.

This isn’t “oops we forgot a step.” This is “our installation process is fundamentally broken.”

The 1,630 lines of comprehensive documentation

4:20 PM — 5:00 PM. Cursor resolves with systematic thoroughness.

Three documents created:

step-by-step-installation.md (950 lines):

  • Assumes ZERO prerequisites
  • Python/Git installation if needed (Mac & Windows separate)
  • 13 detailed steps with verification for each
  • Emphasizes Step 8: pip install -r requirements.txt
  • Troubleshooting for each step

troubleshooting.md (500 lines):

  • 14 common issues with exact error messages
  • Root cause explanations
  • Step-by-step solutions with verification
  • General troubleshooting flowchart

quick-reference.md (180 lines):

  • One-page cheat sheet
  • Copy-paste commands
  • Quick problem/solution table

Total: 1,630 lines of installation documentation

Not “here’s how to install Piper Morgan.” But “here’s how to install Piper Morgan when you have nothing, know nothing, and encounter every possible problem along the way.”

The dependency conflict also resolved:

  • ✅ Removed explicit async-timeout==5.0.1 pin
  • ✅ pip auto-resolves to compatible 4.0.3
  • ✅ Tested in fresh venv — all imports successful
  • ✅ All commits pushed to main

By 5:00 PM, Cursor’s closing message: “The house is clean for Beatrice Thursday! 🎉”

What 1,630 lines represents

Let me be clear about what happened Monday.

We didn’t just write documentation. We discovered — three days before launch — that we had no working installation process.

The documentation we’d written before? Useless. Broken. Would fail immediately for anyone who tried it.

The 1,630 lines aren’t padding. They’re the difference between:

  • “Clone the repo, run setup” (doesn’t work)
  • “Here’s exactly what to do when you have nothing and something goes wrong” (works)

The guides assume:

  • User might not have Python installed
  • User might not have Git installed
  • User might not understand SSH keys
  • User might encounter dependency conflicts
  • User might see cryptic error messages
  • User needs Mac vs Windows specific guidance
  • User needs verification steps to confirm success

Not because users are incompetent. Because installation is genuinely complex and failure modes are numerous.

The alternative would be: Hand Beatrice a repo URL Thursday morning. Watch her encounter ModuleNotFoundError. Try to debug over Slack. Discover each missing piece reactively.

Better: Spend Monday afternoon creating comprehensive documentation. Test it. Fix the dependency conflicts. Document every known issue. Provide troubleshooting for common problems.

The 1,630 lines buy us Thursday morning confidence instead of Thursday morning chaos.

The test coverage vs user experience gap

Monday’s real lesson isn’t about bugs. It’s about the gap between “tests pass” and “users succeed.”

Intent classification bug: Tests passed (classification correct) but users failed (routing broken)

Installation guide: Tests passed (commands work in dev environment) but users failed (commands don’t work in fresh environment)

Response rendering: Tests passed (responses generate) but users confused (responses contradict themselves)

The pattern: We test what we built. We don’t test what users experience.

This is why our “Phase 2” testing matters. Not to prove features work — we have automated tests for that. But to discover what breaks when real humans interact with the system. Note also that without my intervention the LLMs would happily take their automated, partial testing, as fully satisfactory. It helps that I am a real person and know that it doesn’t matter if the tests pass when the software doesn’t actually work.

Discovery testing (from October 26) proving its value: Don’t validate what you built. Discover what users encounter.

Monday discovered:

  • Case mismatch in routing (fix: one line)
  • Installation guide incomplete (fix: 1,630 lines)
  • Dependency conflicts (fix: remove one pin)
  • UX contradictions (fix: validate before claiming)

All found through “try to use it like a new user would.”

None found through “run the test suite.”

What Monday actually achieved

Let’s measure Monday properly.

Features shipped: Zero

Bugs fixed: Three (case mismatch, dependency conflict, missing install step)

Documentation created: Three

Issues identified: Seven (with acceptance criteria)

Audit completed: Yes (6 findings, all documented)

Alpha readiness: Significantly improved

  • The invisible work: Records management, log synthesis, methodology maintenance
  • The testing work: Phase 2 execution, bug discovery, systematic documentation
  • The infrastructure work: Weekly audit, health monitoring, pattern verification
  • The documentation work: Comprehensive installation guides, troubleshooting, quick reference

Not scattered! Systematic, methodical, and productive. Each piece necessary. Each piece building on the others.

The housekeeping enables the testing. The testing reveals the bugs. The bugs drive the documentation. The documentation enables alpha. The audit validates infrastructure health.

Monday wasn’t about one big achievement. It was about systematic progress across multiple dimensions simultaneously.

The Tuesday preview

Monday ends with the bold confidence of the short-sighted LLM: “The house is clean for Beatrice Thursday!” (We shall see!)

Comprehensive documentation. Dependency conflicts resolved. Installation process documented thoroughly. Troubleshooting guides complete. Quick reference ready.

Tuesday will test that confidence against reality: Actually trying to install on a clean laptop following those 1,630 lines.

Spoiler: We’ll find out Tuesday what we missed.

But Monday’s achievement remains valid: We discovered the installation problem three days before launch instead of during launch. We created comprehensive documentation instead of reactive fixes. We established systematic approach to alpha readiness.

The 1,630 lines will need revision. The documentation will prove incomplete. The confidence will be tested.

But Monday established the foundation: When documentation becomes critical, you don’t write minimal instructions. You write comprehensive guides that assume nothing and cover everything.

Because the alternative — discovering your installation is broken when alpha testers arrive — isn’t acceptable.

Monday’s lesson: Better to overdo documentation Monday than underprepare for Thursday.

The 1,630 lines represent hope. Hope that we’ve covered enough. Hope that users will succeed. Hope that Thursday will be smooth.

Tuesday will test that hope against the unforgiving reality of a fresh laptop and a new user following instructions exactly as written.

← Back to BlogAlso available on Medium