03substrate
VERIFYevidence index
Everything this site claims about the work, and where each claim can be checked.
How this index works
The content model makes evidence mandatory rather than optional. A claim is a type that requires a source, so no assertion about this work can be written without the file or commit behind it — the honesty rule is enforced by the compiler, not by discipline.
This page is generated from those records. It is not a separate list maintained alongside them, which is the only reason it can be trusted to be complete.
49 sourced statements across 4 subjects
deadlockd
Evidence for deadlockd
Claim
The safety check copies system state under mutex, then releases the lock before running its O(P²·R) search — so the expensive computation never blocks other goroutines.
Claim
Cycle detection uses an explicit-stack iterative DFS with white/gray/black colouring rather than recursion, so deep process graphs carry no stack-depth risk — and it recovers the actual cycle through a parent array.
Claim
Tests assert exact matrix state, not that the code merely ran: a granted safe request must move Available, Allocation and Need to specific expected values.
Claim
CI runs go mod verify and the full Go test suite, plus an independent frontend production build, on every push and pull request.
Architecture
Two processes and a socket between them. Every decision about safety happens in the Go engine; the browser receives state snapshots and draws them. That split is the design: a correctness engine that needs its own interface in order to be right is not a correctness engine.
Decision
Chose Copy Available, Allocation and Need under the mutex, release it, and run the search on the copy. over Holding the mutex for the duration of the search.. The lock exists to keep the matrices consistent, not to serialise the simulation. A quadratic search inside the critical section makes every other goroutine wait on work that does not need live state.
Decision
Chose An iterative depth-first search with an explicit frame stack and white/gray/black colouring. over Recursive DFS.. Recursion depth would be bounded by user input. A stack overflow in the detector would take the engine down at exactly the moment it was most needed.
Decision
Chose Rebuild the graph on every detection pass — an edge from a process needing an exhausted resource to every process currently holding any of it. over Maintaining a wait-for graph incrementally beside the matrices.. Two representations of the same fact drift apart, and here the one that drifts is the one that decides whether the system is deadlocked.
Decision
Chose Assert exact matrix state in the tests, and ship the visualiser as part of the product rather than as a demo. over A command-line simulator and a suite that checks the code ran.. A granted safe request has one correct effect on Available, Allocation and Need. Asserting that effect is a different claim from asserting no error was returned, and watching the graph close is a different kind of evidence again.
Challenge
Two readers — the safety check and the detector — each need a coherent view of three matrices that a dozen goroutines are mutating. Both take the mutex only long enough to copy and then let go. Every critical section in the engine is short by construction, because the expensive work is always outside it.
Challenge
A deadlock is only worth showing while it forms, which means the client has to keep up with a graph that changes on every allocation. The engine dispatches state snapshots over the socket and the client re-renders memoised nodes. Nothing about the graph is recomputed in the browser, so the rendering cost does not sit on the path that decides safety.
Attribution
Concurrency engine — Banker's Algorithm, cycle detection, recovery — Sagar, 6 of 6 commits.
APIx
Evidence for APIx
Claim
Sole author of the ingestion layer — the observation store, the collector runner, the IndiGo parser and the scheduler — which is the boundary where the system meets untrusted external market data.
Claim
The collection contract is frozen in the repository before data is gathered, so the protocol cannot be adjusted after seeing the results.
Claim
Roughly 5,100 lines of the project's tests are mine, written against an external data source that cannot be relied upon to behave.
Claim
The project publishes no index value, and says so in its own README, because the longitudinal evidence its frozen methodology requires does not exist yet.
Architecture
A collection boundary, an evidence store, and a deterministic statistical spine that is forbidden from importing anything above it. My half is everything up to and including the store — the part that decides what counts as admissible evidence and can prove, months later, what it collected and what it refused.
Decision
Chose A single SQLite file beside a content-addressed directory of raw artifacts, using only the standard library. over A server database or a cloud object store.. Reproducibility is a property of being able to find the original bytes again, not of the database engine. A file can be copied, diffed, and have its checksum committed.
Decision
Chose Store no expected-cells table at all, and make publication take the denominator as a required argument with no default. over A schema field recording what the collector expected to find.. Storing the cells we saw and reading them back as the cells we expected is circular. Coverage measured against our own success can never fall, and would report 100% on a day the collector was blocked.
Decision
Chose Record an attempt for every search — including ones that failed, and ones never made because an earlier search hit an access challenge. over Persisting only the observations that were collected.. Missingness is measurable only from a record of attempts. Without it, a blocked run and a quiet market produce the same rows.
Decision
Chose Tag automated, sandbox and fixture runs in the frame identifier, and admit only primary frames to the index. over Letting automated runs feed the index once the adapter worked.. Adopting automated collection as a production frame is an owner decision recorded in a decision record, not a default that arrives with a working adapter.
Decision
Chose Write the run export and manifest before handing anything to the store. over Exporting after a successful load.. A refused load must not also destroy the record of what was collected — that is the run you most need the audit trail for.
Challenge
The source is hostile and is entitled to be. Quoted prices move constantly, carriers restrict automated access, and a single undocumented collection decision invalidates a longitudinal series. Searches are paced, a site error gets exactly one retry, and an access challenge stops that source for the remainder of the run rather than being retried into a block. Every one of those outcomes is recorded as an attempt.
Challenge
A test suite for a collector cannot depend on the thing it collects from. Roughly 5,100 lines of tests run against fixtures and a sandbox mode, behind a gate that refuses live clearance unless it has been granted explicitly.
Challenge
The repository vendors a large engineering framework that is not the product, and its version numbers and readiness reports describe itself. The layout states which trees are the framework and which are APIx, file by file, and marks every empty package as a reserved slot rather than working code.
Open work
Run the second collection wave, so the longitudinal step has a matched t and t−7 pair to compare. The engine is implemented and tested and still publishes nothing, because one wave produces zero matched pairs and the chaining guard refuses an index value without them. The next run is what unlocks the first real number.
Open work
Establish a second source and a second route, so the panel stops being one carrier on one sector. National representativeness is recorded as not established. Deduplication and source precedence are implemented but degenerate on a single-source panel — exercised is not validated.
Attribution
Three contributors. I am the largest by commits and own the acquisition boundary; the statistical core and the interface work are not mine.
Attribution
Ingestion, collectors, scheduler, collection and analysis tooling — Sagar, 16 of 29 commits.
VAYU-DRISHTI
Evidence for VAYU-DRISHTI
Claim
Configuration refuses to boot the server on DEBUG=True with ENVIRONMENT=production. The misconfiguration raises at import time, before the application accepts a single request.
Claim
Request-ID middleware binds a UUID into structlog contextvars, so every log line emitted during a request carries the same trace ID — and the ID returns to the caller on the X-Request-ID header.
Claim
Alembic runs migrations through asyncio.run() and create_async_engine(), so asyncpg is the only PostgreSQL driver in the project. psycopg2 is deliberately absent rather than carried as a second dependency.
Claim
The DATABASE_URL is a computed field assembled from separate components with quote_plus encoding, so special characters in credentials cannot corrupt the connection string.
Architecture
A FastAPI application factory over an async PostGIS data layer, with configuration validated and logging configured before anything else is constructed. The models and the AQI calculation sit on top of this and are not mine. The platform underneath them is.
Decision
Chose Inject a UUID per request in middleware and bind it into structlog contextvars, returning it on X-Request-ID. over Per-module logging with no correlation identifier.. Binding into contextvars means every line emitted anywhere during that request carries the id without a single call site passing it — through middleware, handlers and services alike. Returning it on the header means the caller can quote the id for their own failed request.
Decision
Chose Validate settings at import time, and raise on DEBUG=True with ENVIRONMENT=production in a model validator. over Reading environment variables where they are needed and checking at use time.. The failure has to happen before the application accepts a request. A check at the point of use fires after the thing it was guarding has already been exposed.
Decision
Chose Derive it as a computed field from separate components, encoding user and password with quote_plus. over Accepting a raw connection string from the environment.. Special characters in a password corrupt a hand-assembled URL, and a single opaque variable makes accidental exposure the easy path rather than the careless one.
Decision
Chose Run migrations through asyncio.run() with an async engine, keeping asyncpg as the only driver. over Installing psycopg2 alongside asyncpg for migrations.. Two drivers means two connection behaviours, two sets of type adapters and a second thing to keep configured — for a task that runs a handful of times.
Decision
Chose Serve /docs and /redoc in development and staging, and disable them in production. over Leaving them enabled everywhere because they are useful.. The people who need them are not in production, and the environment already knows which one it is — so the decision can be made by configuration rather than by remembering.
Challenge
Three of the four people on the project never touch the platform, and their work has to attach to it without editing it. An application factory rather than a module-level app, a versioned router, and typed schemas at the boundary — so a model or an endpoint is added by registration, and tests can build an application with custom settings without affecting any other test.
Challenge
Observability has an ordering problem: any logger created before logging is configured is configured wrongly, and will be for the life of the process. Settings load and logging is configured as the first module-level actions in the entry point, before the factory runs and before any logger is created.
Open work
Fill the lifespan hook: database pool warm-up, model loading and background task startup. The lifespan context manager is in place and the code says that is where those belong, but it does nothing yet — so the first request after a deploy currently pays for a cold pool.
Attribution
Four contributors. I own the platform everything else runs on; the machine learning and the AQI calculation are not mine.
How Sagar works