← Back to Blog
Building in Public

When Investigation Becomes Certainty

christian crumlish•
Multiple investigation paths converging on a single confirmed answer, uncertainty collapsing into fact.
“All the tests agree!”

November 19 to 20

Sometimes you don’t know what’s blocking you until multiple investigations from completely different angles all point to the same answer. You think you’re doing unrelated work — recovering test infrastructure here, answering architecture questions there, improving pass rates over there — and then everything converges. The answer becomes undeniable not because one investigation proved it, but because three separate investigations independently arrived at the same conclusion.

Our lack of adequate security currently blocks alpha testing. Not “should be improved” or “would be nice to have.” Blocks. Non-negotiable. And we only knew this because we looked at the system from enough different perspectives to see the pattern.

When tests stop hiding

The test suite had been lying to us. Not maliciously — it just couldn’t tell the truth because one misplaced file was hiding 617 tests from pytest. A single __init__.py in tests/services/ created a shadow package that blocked pytest from importing the real services/ module. Zero tests collected. Zero tests running. Zero failures visible.

The architecture test had finally revealed this the day before. Moving tests from tests/services/ to tests/unit/services/ suddenly made 617 tests discoverable. But discoverable isn't the same as passing. My Code Agent spent the morning fixing collection errors - 19 missing async keywords, five import mistakes, syntax errors - the mechanical cleanup work that reveals what's actually broken once tests can run.

By mid-morning, all 617 tests were collectible. Time to run them and establish a real baseline. The command ran: pytest tests/unit/services/ --maxfail=0. Let everything fail that needs to fail. Don't stop at the first problem.

The results came back: 422 passing (68.4%), 142 failing, 53 errors. A 68.4% pass rate sounds terrible until you realize the alternative was 0% visibility. We’d been building with hidden test failures for months. The shadow package gave false confidence — if tests don’t run, they can’t fail, and if they can’t fail, everything seems fine.

The failure analysis revealed patterns. Fifty-three tests failed because of missing fixtures. Forty-four tests were written for an old API design that never got implemented. Forty tests expected spatial workflow integration that was still in progress. These weren’t random failures — they were systemic issues that needed systematic solutions.

But that 68.4% baseline was real. Accurate. Actionable. We finally knew the actual state of the test suite instead of the assumed state.

When brilliant questions reveal what’s missing

While test infrastructure recovered, a different investigation began. Ted Nadeau — brilliant computer scientist, someone whose architectural judgment I trust completely — had questions about Piper’s architecture. Not surface questions. Deep questions about singletons and scalability, database design patterns, security implementation, architectural decisions.

My Research Agent spent over four hours responding. The deep-dive research session created comprehensive reports covering database design, stored procedures, primary key naming, table naming conventions. Ted’s questions were making us explain and defend architectural choices we’d made implicitly. Every answer required evidence, not assertions.

Then came Ted’s follow-up questions about database design. Not just “how does this work” but “why these specific choices.” Stored procedures? We don’t use SQL procedures — our application-layer workflows effectively function as stored procedures (which turned into ADR-043 later). Primary key naming? Currently unprefixed (id), Ted prefers prefixed (user_id). Table naming? Plural (users), Ted suggests singular (user).

But the most interesting question was about database annotations — a novel pattern Ted proposed where you annotate WHY data changed, not just WHAT changed. This could enable AI learning from human decision patterns. It was the kind of insight that might be patent-worthy.

Side note: I can’t tell you how long and anxiously I’ve waited for a real programmer to kick the tires on this work!

The research created seventeen GitHub issues. Most were database design improvements, migration planning, quality assurance gaps. But two issues stood out:

Issue #323: RBAC Implementation (20–24 hours) — marked CRITICAL BLOCKER
Issue #324: Encryption at Rest (24–30 hours) — marked CRITICAL BLOCKER

Those weren’t suggestions. Those weren’t “nice to have.” Those were blockers. Ted’s questions about security implementation had revealed what we didn’t have: role-based access control, encryption at rest. For a single-user alpha, maybe acceptable. For multi-user alpha with external testers? Absolutely not acceptable.

The research didn’t just answer Ted’s questions. It revealed what we couldn’t ship without.

When test recovery reveals the path

The next day brought test transformation. My Claude Code agent had been systematically fixing the test suite — not heroics, not rushing, just methodical work. Container initialization patterns. PyPDF2 migration. Webhook signature verification fixes. The kind of infrastructure work that doesn’t feel dramatic but compounds into significant progress.

The test suite had jumped from 617 tests collectible to 2,306 tests collectible — a 257× increase. That shadow package had been hiding far more than we realized. But more importantly, the pass rate was climbing: 68.4% → 85%+. Not from fixing bugs in production code, but from fixing test infrastructure so tests could actually run and report accurately.

SLACK-SPATIAL integration recovered from 61% to 85% passing across three phases. Quick wins, OAuth methods, pipeline fixes. Eighteen tests that had been blocking now passing. The systematic approach was working — fix infrastructure, tests reveal real problems, fix real problems, infrastructure gets stronger.

But the most significant development was the security audit findings. My Chief Architect had been reviewing the system comprehensively, and the assessment was clear: three FileRepository methods exposed cross-user file access vulnerabilities. If endpoint authentication got bypassed somehow, users could access other users’ files at the data layer.

This was a P0 vulnerability. Not “should fix eventually.” Fix immediately.

None of this would have even been detected as long as I was the only human user in the system.

When everything points to the same answer

By late afternoon, three separate investigations — test infrastructure, Ted’s architecture review, security audit — had all identified the same critical gap: security.

The test recovery showed we could achieve high pass rates through systematic work, but pass rates don’t matter if the security model is incomplete. Ted’s architecture review validated that our overall design was sound, but explicitly flagged RBAC and encryption as missing critical components. The security audit found actual P0 vulnerabilities that couldn’t ship to external users.

Three different perspectives. Three different investigation methods. Same conclusion.

My Chief Architect synthesized everything into a clear strategic picture. Sprint S1 (Security Foundation) would require 81 hours total:

  • SEC-RBAC: 24 hours (P0 CRITICAL) — Role-based access control
  • SEC-ENCRYPT-ATREST: 24 hours (P0 CRITICAL) — Encryption at rest
  • Python 3.11 upgrade: 8 hours (security patches expired October 2025)
  • Performance indexes: 6 hours
  • Windows compatibility: 3 hours
  • Architectural singleton pattern: 16 hours

RBAC and encryption weren’t suggestions. They were blockers. Non-negotiable before multi-user alpha. The external validation from Ted, the test infrastructure revealing system health, the security audit finding P0 vulnerabilities — everything converged on the same answer.

The decision wasn’t “should we do security work.” The decision was “security work happens now, before any external alpha testing with multiple users.”

What convergence may reveal that single investigations can miss

Any one of these investigations alone might not have created certainty. Test infrastructure recovery showed 85% pass rates — great, but doesn’t necessarily mean “stop everything and fix security.” Ted’s architecture review identified RBAC and encryption gaps — important, but maybe deferrable if you’re still in single-user alpha. Security audit found P0 vulnerabilities — serious, but potentially fixable with quick patches.

But three investigations converging? That’s certainty.

The test recovery proved we could do systematic infrastructure work and see real results. The architecture review validated that our foundation was solid and identified exactly what was missing. The security audit found concrete vulnerabilities that demonstrated those missing pieces weren’t theoretical concerns.

Each investigation strengthened the others. Test infrastructure recovery showed our methodology worked. Ted’s validation confirmed our architecture could support what we needed to build. The security audit made the missing security features impossible to defer or minimize.

This is what systematic building enables. You’re not just implementing features. You’re creating multiple feedback loops that all report on system health from different angles. When they all start pointing to the same issue, you know you’ve found something that actually matters.

When external validation accelerates internal decisions

Ted’s involvement did something important beyond just identifying gaps. It accelerated decision-making. When your internal team identifies security gaps, there’s always a temptation to defer: “We’ll get to it later.” “It’s alpha, we can ship with known gaps.” “We’ll add security in the next phase.”

But when an external expert whose judgment you trust deeply looks at your system and says “these specific things are critical blockers,” it removes ambiguity. It’s not your team being cautious or perfectionist. It’s an independent assessment confirming what you suspected but might have minimized.

The seventeen GitHub issues from Ted’s research weren’t just task lists. They were external validation of internal concerns. When our security audit said “P0 vulnerability,” Analysis of Ted’s probing questions told us “RBAC is a critical blocker.” Two independent sources, same conclusion. That’s how you know you’re not overthinking it.

This is the value of bringing experienced outside perspective into development. Not to tell you what to build, but to ask hard questions that reveal what you haven’t built yet. Ted didn’t design our security model. He asked questions that made us realize we needed a more complete security model before shipping to external users.

What certainty costs and buys

Stopping feature work to fix security infrastructure costs time. Sprint S1 would take 81 hours — roughly two weeks of focused development. Two weeks not adding features, not fixing user-facing bugs, not improving UX. Just hardening security infrastructure that users won’t directly see or appreciate.

But shipping without security would cost more. The first external security researcher finding the cross-user file access vulnerability would be catastrophic. The first multi-user alpha test exposing role-based access control gaps would be embarrassing. The first encryption audit failing would block any serious adoption.

The convergence revealed certainty: security blocks alpha. Not “delays alpha” or “improves alpha.” Blocks. You can’t launch multi-user alpha testing with P0 vulnerabilities and missing critical security features. The external validation confirmed it. The test infrastructure proved we could do systematic work. The security audit quantified the risk.

So the decision became simple: do Sprint S1 now, before external alpha, or don’t do external alpha. There’s no third option where you ship known P0 vulnerabilities to external users and hope nobody notices.

Certainty removes the temptation to defer. When multiple investigations from different angles all point to the same blocker, you stop debating whether it’s really a blocker. You fix it.

The systematic building advantage

This convergence moment only happened because we were building systematically across multiple dimensions simultaneously. Test infrastructure work, external architecture reviews, security audits, test pass rate improvements — all happening in parallel, all reporting on system health.

If we’d only been doing feature work, we wouldn’t have discovered the shadow package hiding 617 tests. If we’d only been fixing tests, we wouldn’t have engaged Ted’s architectural expertise. If we’d only been focused on shipping, we wouldn’t have run comprehensive security audits.

Systematic building creates multiple feedback channels. Each channel reports different information. When they start converging on the same signal, you know you’ve found something real.

The test suite went from 0% visibility to 68.4% baseline to 85%+ pass rate through systematic infrastructure work. Ted’s architecture review validated our foundation while identifying specific gaps. The security audit found concrete vulnerabilities. Three feedback channels, three perspectives, one conclusion: security blocks alpha.

That’s the payoff of patience in process. You build enough feedback mechanisms that convergence becomes possible. And when convergence happens, certainty follows.

The shadow package revealed what we couldn’t see. Ted’s questions revealed what we hadn’t built. The security audit revealed what we couldn’t ship. Together, they revealed what we needed to do next: Sprint S1, 81 hours, non-negotiable, before any external alpha testing.

Sometimes investigation becomes certainty not through one perfect insight, but through multiple imperfect investigations that all point the same direction. That’s when you know what to do next.

← Back to BlogAlso available on Medium