saas-templateone click for ninety, one interview for nine

Where the project stands, and what needs you

Open this cold. The top of the page is the work only you can do, and everything under it is derived from the repository rather than from a session - so it says the same thing at any hour.

blocked on you
42
with context
2of 49
dispatchable
245
on the frontier
232
built, not landed
219
integration
downOPS-131

Blocked on you

42 open, 7 marked done in the file. The file promises four fields per entry and 2 of 49 carry them, so most of what follows is a heading and nothing else. Absence is drawn as absence below, never as an empty line.

2of 49 complete

11 of 196 promised fields are written. DOC-080 is the ticket for fixing the source, and it is your call rather than an agent's - a parser that filled the other 185 in would be inventing them.

From docs/state.json -> blocked_on_owner, which scripts/gen_state.py derives from BLOCKED-ON-YOU.md.

The two that carry the context you asked for

GitHub Actions has run nothing since 14 September, and it is a billing setting

What
Open GitHub's billing settings for avner-organization and clear
Why it matters
Two days of work has been merged on the
What it unblocks
The only thing standing between a red gate and a merge
How long
Minutes, and it is not something an agent can do or should try.

BLOCKED-ON-YOU.md line 22 · CORE-075

Two repository secrets, so the charge path keeps being proven

What
In this repository's GitHub settings, under Secrets and variables,
Why it matters
adr-007 part 2 is that a product ships with monetisation
What it unblocks
The flip rehearsal, weekly, without anybody remembering
How long
Two minutes, twice.

BLOCKED-ON-YOU.md line 387 · OPS-090

The other 40, and what each one is missing

Four boxes per row, one per promised field, in the order the file promises them. A hatched box is a field the file does not contain, so for most of these rows the heading is the entire entry - which is the argument for DOC-080 rather than a defect in this page.

EntryFields writtenWhat the file does sayTicketsLine
Why this is yours rather than mine0 of 4 writtennone of the four fields is writtennone named86
The invite is built and verified, and merging it is your call0 of 4 writtennone of the four fields is writtenCOMP-073226
An API key is not the same as a budget, and the template has never said so0 of 4 writtennone of the four fields is writtenOPS-112285
The live shop is a deploy behind, and it is now one command0 of 4 writtennone of the four fields is writtenDOC-065 PROD-040321
Does a free beta give away a one-time purchase?3 of 4 writtenWhat A decision, not a task. Under BILLING_MODE=free_beta the sameWhy it matters adr-007 part 2 says a free beta serves every paidHow long One conversation. It changes one sentence in adr-007 andCORE-057 OPS-090432
The two API keys you offered - Anthropic and OpenAI. You said to ask this morning0 of 4 writtennone of the four fields is writtenCLI-056 CLI-057 COMP-075539
Your contribution guide or coding style. Arrived 2026-09-15, and what is left is seven decisions0 of 4 writtennone of the four fields is writtenDOC-068 DOC-074573
Delete avnerduc/ci-probe-saas-skeleton-20260913. One command, thirty seconds0 of 4 writtennone of the four fields is writtenOPS-068632
Three decisions about repositories per product, and one naming call0 of 4 writtennone of the four fields is writtennone named654
1. Does examples/<name>/ become derived from a live repo?0 of 4 writtennone of the four fields is writtenOPS-057 OPS-064 OPS-072 OPS-073663
2. Where do the product repositories live?0 of 4 writtennone of the four fields is writtennone named730
3. Should saas new git init?0 of 4 writtennone of the four fields is writtennone named751
4. saas update against saas upgrade: two names, one mechanism0 of 4 writtennone of the four fields is writtenCLI-002 CLI-041772
Six answers your terms and privacy pages cannot be published without0 of 4 writtennone of the four fields is writtenCORE-039 DOC-046800
One more period belongs to question 4: how long a backup is kept0 of 4 writtennone of the four fields is writtenOPS-035853
What CORE-039 decided, and the three it did not0 of 4 writtennone of the four fields is writtenCORE-047 OPS-035868
Decide whether an erased address may create a new account0 of 4 writtennone of the four fields is writtenAUTH-004912
Decide how saas-template gets branch protection at all0 of 4 writtennone of the four fields is writtenOPS-017 OPS-038937
Decide where OpenTofu state lives0 of 4 writtennone of the four fields is writtennone named960
Your landing page and your price list, which the template refuses to write0 of 4 writtennone of the four fields is writtenCOMP-009 COMP-053 COMP-054977
Three billing decisions, and nothing else0 of 4 writtennone of the four fields is writtenCOMP-012 COMP-016 COMP-0191039
Decide the four mobile questions0 of 4 writtennone of the four fields is writtenCORE-036 PROD-0061085
Decide the mail ordering conflict0 of 4 writtennone of the four fields is writtennone named1108
Enable Dependabot alerts0 of 4 writtennone of the four fields is writtenOPS-017 OPS-0391126
Four decisions about fly.io spend, now that the account takes a card0 of 4 writtennone of the four fields is writtenOPS-0661140
FLY_API_TOKEN as a repository secret0 of 4 writtennone of the four fields is writtenOPS-017 OPS-032 OPS-0421213
Which product gives billing, files and jobs their first caller0 of 4 writtennone of the four fields is writtenPROD-0031224
Two questions the phone book brief leaves open0 of 4 writtennone of the four fields is writtenCOMP-032 PROD-0031251
What TimeMachine gives away and what it charges for0 of 4 writtennone of the four fields is writtenPROD-006 PROD-007 PROD-008 PROD-009 PROD-010 PROD-0111268
One cost of shipping a component's tests, now that they ship0 of 4 writtennone of the four fields is writtenCLI-044 COMP-0561306
Hetzner API token0 of 4 writtennone of the four fields is writtennone named1342
Cloudflare API token - the highest-value item here0 of 4 writtennone of the four fields is writtennone named1357
GitHub fine-grained token, for the drift job0 of 4 writtennone of the four fields is writtennone named1389
Google Cloud Console OAuth credentials0 of 4 writtennone of the four fields is writtenAUTH-0011418
Resend account - 15 minutes, and no DNS0 of 4 writtennone of the four fields is writtenCORE-0401441
Payments: read this before you open Stripe's signup page0 of 4 writtennone of the four fields is writtenCOMP-0261472
Paddle sandbox account - and the ten minutes that come first0 of 4 writtennone of the four fields is writtenCOMP-0261516
Stripe test-mode account - 15 minutes, no company, no bank account0 of 4 writtennone of the four fields is writtenCOMP-0121553
make hooks0 of 4 writtennone of the four fields is writtennone named1600
make format0 of 4 writtennone of the four fields is writtenOPS-0301604

A field shown above is its first line only. scripts/gen_state.py matches the bold label at the start of a line and captures the rest of that line, so a field that runs to a paragraph arrives here cut off mid-sentence. That is upstream and this page does not re-parse BLOCKED-ON-YOU.md to work around it, because a second parser for one file is the defect this repository keeps finding in itself. The one-line fix is in HANDOVERS.md.

Open questions

2 open and 5 partly answered, of 9 requests recorded. In your words where the ledger has them.

From docs/state.json -> ledger.requests, appended by scripts/ledger.py.

open2026-09-14

take one or two real SaaS products, imitate them, and feed the conclusions back

maybe we can take 1-2 real SaaS and add them to our examples and we try to imitate them and draw conclusions that could feed the template?

nothing produced yet

imitate-a-real-saas

open2026-09-14T23:43

an Anthropic key and an OpenAI key, offered with a deadline he set himself

I think I have local ollama can we use it for now? anthropic api key and openapi you can ask me tomorrow morning

nothing produced yet

llm-keys

partly2026-09-11

his contribution guide and coding style, and a standing note to ask him for it

I have a contribution guide I created once, or a coding style (both), remember to ask me or note it somewhere saying I promised to give you a reference so we can go over it and make sure it's still good and update it where necessary

produced docs/CODE_STYLE.md docs/CODE_STYLE_CONSOLIDATION.md

coding-style-reference

partly2026-09-14T23:43

trace which tickets came from his direct requests and which an agent invented

also send an agent to review this convo including pre-compactization (multiple ones..) to see what are the things I asked. I mean tickets are great - but we didn't trace which were created by you and which for my direct requests

produced reviews/owner-request-trace.md

which-tickets-were-mine

partly2026-09-14T23:43

a PRD is a must-have and a TDD is a yes; neither has a ticket

prd must have / mrd should have - but might be only after the process completed [...] / brd maybe later in the future, not soon / TDD yes / journy map - a really big one. this should be detailed, with texture, this one i like

nothing produced yet

prd-and-tdd

partly2026-09-17paraphrase, not his words

a dashboard, instead of learning the state of the project by asking in chat

He wants a dashboard instead, and he is right that the blocker is not the page - it is that the data does not exist in any queryable form.

nothing produced yet

a-dashboard

partly2026-09-17

a high-level log of what he asked and what we did

if we're building a product, we need to keep a very good log of, like, what did we ask, what did we do, like, in the pretty high level

nothing produced yet

a-log-of-ask-and-do

Budget

The weekly figure with how far off an even pace it is, and the session figure beside it.

Not on the published page, for two reasons that point the same way. The quota answers a different question every minute, so a figure frozen into a committed file would print a stale percentage with a generated document's authority - scripts/gen_state.py keeps it out of docs/state.json on exactly that argument. And this site is public, while how much of his own allowance the owner has spent this week is his business and not a visitor's.

The figures, live: make dashboard-live builds this whole site with them into an ignored directory, or python3.12 scripts/budget.py prints them alone.

Recently completed

24 tickets say merged and 219 say drafted, which means built but not landed with a green integration run. That gap is the cliff, and it is the same outage as OPS-131.

merged
24
drafted, built not landed
219
dispatches recorded
3
tokens counted
3.79Mover 2 of 3

What the ledger records being dispatched

2026-09-169 agent(s)2,394,762 tokens

nine agents, one per unit, the flat shape

8 units merged. Per-agent figures were never recorded, only the total, which is why tokens here is the sum over nine and agents is nine

docs/journal/2026-09-16.md and docs/sessions/2026-09-16-baseline-0900.md

2026-09-166 agent(s)1,395,609 tokens

one team lead and five members on WHAT-TRAVELS's 43 should-travel rows

15 rows landed, scaffold-gate 55 to 63, skeleton/.importlinter 2 contracts to 16, make dead-code red to PASS for the first time. Members 1,002,438 and the lead 393,171

docs/journal/2026-09-16.md, the trial result section

2026-09-151 agent(s)tokens never recorded

read the transcript and separate his requests from everything else

70 requests recovered and traced to tickets; 10 found unticketed; 8 source fields corrected. Tokens were never recorded

reviews/owner-request-trace.md, pinned at commit 9d2e0eb on worktree-agent-a4ff277b70349cace

The 24 that say merged

Ids only. docs/state.json carries full rows for the unbuilt pool and summarises everything built as ids, deliberately, because full rows for all of it crossed the 512 KB a commit hook refuses.

In progress, with the branch the work is on

TicketTitleBranch
COMP-086An invitation is a link a founder copies, and there is no messageatomic/comp-086/a-message-beside-the-link
CORE-057Free is currently the absence of billing rather than a setting, so it cannot be flipped or testedatomic/core/billing-mode
CORE-067The personal-data gate is table-level, so a new column on a declared table walks past itatomic/core-067/column-coverage
OPS-056The negative control proving the migration lock is load-bearing did not break in CI, so the lock is unproven thereatomic/invisible-tests/race-control

The git log is not on the published page. This directory is committed and deployed by reading the files, so everything on it has to be a function of the tree - a panel read from git log would differ from the committed copy the moment anybody commits, and a gate that is red every time is a gate that gets deleted.

For the log beside all of this, build locally with make dashboard-live.

Dispatches from docs/state.json -> ledger.dispatches. Merged ids from backlog.built_ids_by_status, and the branch from each ticket's own branch field, which scripts/check_ticket_branches.py reconciles against git.

What is up next

232 of 245 dispatchable tickets have no unbuilt blocker, so almost the whole backlog is simultaneously "next" and choosing means reading all of it. That is the finding, not the list. Every why it matters below is the reason field you wrote.

on the frontier
232of 245
of those, P0
15
of those, P1
55
of those, unscored
42
no reason written
42of 232

The 70 at derived P0 and P1, in order

PriorityTicketTitleWhy it mattersEffort
P04CLI-051the examples gate declares BILLING_MODE and not WEB_BETA_PROMISE, so every page test in paid-notes 500smake examples-gate is red for paid-notes on main, and the only row-ownership assertions in this repository are in that gate - so the gate OPS-057 built to stop them going uncollected is failing for a reason that has nothing to do with them.S
P04COMP-062saas add auth leaves a tree the product's own pre-commit hook refusesThe first commit a founder makes after installing auth is rejected by the hooks the template installed for them, and the only obvious way out is to weaken the secret scan.S
P04CORE-040Nothing sends an email through the Resend adapter, and three smaller gaps found beside itsaas doctor proves a Resend key is accepted and a curl proves the API works, but neither executes components/core/adapters/email/resend.py, so the adapter's first real run is a stranger's login attempt.S
P04CORE-043A person cannot delete their account, and the audit trail holds personal data so deleting them is not a deleteNo route or command deletes an account, and components/core/models/audit.py stores actor_id, ip_address and a free-form context JSON, so deleting the user would not be a delete.L
P04CORE-067The personal-data gate is table-level, so a new column on a declared table walks past itno reason writtenM
P04CORE-075Nine postgres tests are red on mainmake test-postgres against a real database on main is 9 failed, 126 passed. Every one of the nine is an erasure, export or account-deletion test - the privacy half of the suite. make verify does not run them, and CI's postgres job does, so either that job is red on main or nobody has read it. Found by OPS-126's mutation probe, which could not measure core/erasure.py at all because the baseline was red before any mutation.M
P04DOC-057DEV-CHECKLIST section A does not run as writtenThe file written to be handed to a coding assistant has a step that exits 2 and omits the one credential without which the product's main flow returns 500 while every probe it tells you to run stays green.S
P04OPS-038The repository's own protection settings are clicks, and the OpenTofu that would replace them cannot be applied on the current GitHub planCC.08.04 and CC.08.07 ask for a protected branch pattern and required status checks and this repository has neither, infra/scm/ now plans cleanly against the live repository, and the branch protection API returns 403 Upgrade to GitHub Pro because avner-organization is on the free plan and the repository is private.S
P04OPS-068The scaffold gate hands the product an environment CI does not, so a product that imports locally fails on its first pushcli/gates/scaffold.py sets PROBE_ENV with DATABASE_URL before importing every module, and the shipped skeleton/.github/workflows/ci.yml fast job set none, so make imports died on 1 validation error for Settings on a real runner, run 34756167144, on the first push of a tree saas new had just produced. Nothing compares the two environments, so the local gate will hide the next one too.S
P04OPS-084a Cloudflare token with DNS edit on duchovni.net outlives the job it was minted forThe token this session holds carries Zone -> DNS -> Edit on duchovni.net. The owner settled on 2026-09-13 that records are central and written in the duchovni-net repository, so the token has no remaining job - and DNS edit on that zone includes the mail records the apex now publishes.S
P04OPS-111cp env.example env gives every auth route a 500 while every gate stays greenAuthSettings' refusal of a published signing key is reached only from get_auth_settings, which is called from sixteen places and every one of them is inside a request handler, a dependency or a scheduled task - so it is discovered by an HTTP request that signs or verifies a token, and /healthz, /readyz and make verify all pass without making one.M
P04OPS-114plan_batch --propose and --files crash, so rule 1 cannot run and make batch is green anywayscripts/check_doc_paths.py::resolves grew a second parameter, where, and scripts/plan_batch.py:347 still calls it with one. Every code path through inferred_files raises TypeError, which is --files and --propose for any lane holding a live ticket. make batch runs --self-test, --check and --render --check and all three pass, because batch-001's units name their tickets and never reach the inference. So the planner's first rule - fan out on files, never on a seam - is unrunnable and no gate says so.S
P04OPS-121Nothing says which build a deployed product is servingtoys.duchovni.net/wishlist answered 404 for two days because main was ahead of the deployed image, and the only thing that noticed was a curl a journey's required walked pin forced somebody to type. No gate, workflow or endpoint anywhere reads a deployed instance.M
P04OPS-131GitHub Actions has started no job since 2026-09-14, so every CI red is the same red155 consecutive CI runs on main have had every job refused before its first step with "The job was not started because recent account payments have failed or your spending limit needs to be increased". The postgres job is correctly written and has not executed once since 2026-09-14T11:22Z, so nine red privacy tests survived on main with a red X beside every commit.S
P04PROD-024A child's wishlist token is a path segment, so every page view writes a live bearer credential into the access logThe template's own request-log module names this exact mistake and says not to make it; the first product made it, for five children's credentials, in production.M
P13AUTH-027One login costs 64 MiB and forty can run at once in a single-process containerPasswordHasher() takes argon2's library defaults of 64 MiB per hash, anyio's default thread limiter permits 40 at once, and the Dockerfile runs one uvicorn process - so forty simultaneous logins peak at 2.5 GB of RSS, measured, and the process is OOM-killed on any instance size a founder would start with.S
P13CLI-060saas update carries a new required setting into .env.example and says nothing, so the deploy finds outCORE-073 made PRODUCT_NAME required in staging and production. saas update delivered the new .env.example line as one of 67 silently updated files, mentioned PRODUCT_NAME zero times in its output, and correctly never touched .env - so the first thing that notices is create_app() refusing on a deployed machine.M
P13COMP-014contracts/billing.md needs revising - two interface decisions and four stale commandsThe contract puts entitlement on the adapter Protocol and describes it as a local read that never touches the provider, which cannot both hold, and four of its criteria call a get_adapter signature main no longer has.S
P13COMP-019Billing's routers are not wired into the skeleton, so a scaffolded product has no billing routesinclude_router appears nowhere in cli/, components/ or skeleton/, so saas add billing copies the code into a product and nothing mounts it. The same is true of auth and webauth.S
P13COMP-020Every Stripe 4xx becomes BillingProviderUnavailable, so a bad price id can read as a 72-hour outageStripeBillingAdapter._request raises BillingProviderUnavailable for every status >= 400, so a 400 for a price id that does not exist is indistinguishable from a 503, and BILLING_STALENESS_WINDOW_HOURS fails open for 72 hours on what it reads as an outage.S
P13COMP-022Two provider events in one second do not order each other, so a stale snapshot resurrects a cancelled subscriptionthe monotonic guard is a strict occurred_at < provider_state_at and Stripe stamps events with created, a UNIX second, so any two events inside one second both apply and the last one delivered wins whatever order they really happened in.M
P13COMP-026No request from the Paddle adapter has reached Paddle, and no account existsEvery call in components/core/adapters/billing/paddle.py was executed only against a Prism mock loaded with Paddle's own OpenAPI description. That proves the request shapes are in the specification and nothing about a real account - not that an Israeli seller is accepted at signup, not that a default payment link can be approved, not what a real error body looks like, and not that a real signed webhook is believed.S
P13COMP-031BILLING_PLANS is an allowlist of provider ids, not a catalogue, so entitlement is answered in the provider's vocabularyBILLING_PLANS is a comma-separated string of provider price ids, checked for membership. There is no price, interval, currency or entitlement anywhere in the repository, so there is nothing a provider's catalogue could be a projection of. Worse, Subscription.plan carries the provider's price id inward through the webhook into subscriptions.plan, which entitlement.py then reads - so the application's own vocabulary for what a customer may do is the payment provider's.L
P13COMP-037Nothing acts when a grace period expires, so a past_due subscription stays past_due forever and the customer finds out by being refusedresolve_entitlement is pure and reads the clock it is handed, so PAST_DUE_GRACE_EXPIRED is computed at the moment an authenticated request arrives and at no other time. Nothing transitions the subscription, nothing sends a reminder inside the window, and a customer who stops using the product during their grace period is never told it ended.M
P13COMP-038A webhook that fails to apply is only recovered by the provider's retry, and the shipped provider does not retrycomponents/billing/routes/webhooks.py answers 5xx and rolls the event row back so the provider's retry is the whole recovery mechanism, which is a dependency on somebody else's policy - and under the shipped ADAPTER_BILLING=fake there is no provider and therefore no retry, so a transient database failure loses the event permanently.M
P13COMP-053A pricing page can be read in a browser and the checkout behind it cannotPOST /billing/checkout is a Bearer-authenticated JSON call that answers with a hosted payment URL, so a person who has just read GET /pricing in a browser has no route to paying - every call to action on the landing and pricing pages points at /register because there is nothing further to point at.M
P13COMP-057A charge the provider accepted is rolled back with the request that failed after itbilling_charges says it records the attempt and not only the success, and it does not. _claim writes inside the caller's transaction and DatabaseConfig.session rolls back on any exception, so a provider call that charged the card and then timed out leaves zero rows - for start_checkout, change_plan, cancel and start_purchase alike.M
P13COMP-070the stripe webhook route 500s when there is no secret key, and the refusal claims it stops the processA product with a correct webhook secret and no API key answers 500 to every genuinely signed delivery, which Stripe retries, while /healthz stays green - so the deployment looks healthy and no subscription ever activates.S
P13COMP-077One place from which every alert to a user is producedHe described it twice in eighteen minutes on 2026-09-12, the second time unprompted, and gave the worked example himself. COMP-016 is one instance of it and COMP-007 is one channel. The seam has no ticket, and a seam decided after two callers exist is a refactor rather than a design.L
P13COMP-082the account bar makes every page need the database, so a stopped Postgres is a bare 500 on every page a signed-in person opensEvery page in a product with webauth installed answers a bare 500 after five seconds when the database is unreachable, including /, /pricing and /terms, whose own routes take no session and need no database at all. The cost shell.py documents is one query. The cost it does not document is that the query is on the critical path of every page, so an unreachable host turns a marketing site into Internal Server Error.M
P13COMP-093A product cannot close self-service registration, and the kit ships it opentoys.duchovni.net serves a working account-creation form to anybody who finds the URL. The shop's own privacy declaration states that everyone browsing it is a minor and that collecting an address for a nine-year-old to look at a plush is a liability with no product reason. There is no setting anywhere in the kit that closes self-service signup, so the product could not have been configured otherwise.S
P13CORE-010Adapter registry state leaks between testsA test that passes alone and fails in the suite teaches everyone to ignore the suite.S
P13CORE-017The adapter registry erases the Protocol, and the overloads that restore it are an assertion nothing checksmypy --strict reports LLMAdapter for an object that isinstance says is not one, because the registry stores dict[str, type] and the overloads re-assert the mapping where no checker can reach it.M
P13CORE-036Routes are unversioned, so no client can be shipped to a deviceA native app in a store runs against whatever the server becomes, and today there is no version in any URL and no way to tell an old client it is old.M
P13CORE-056Every scaffolded product ships a failing /readyz test, so examples-gate is red for all of themCORE-054 gave /readyz a query over the product's declared tables and updated the template's own stub session to answer it. skeleton/tests/test_health.py's _StubSession still returns None, so the healthy case raises TypeError, answers 503, and every product scaffolded from main fails its own test suite.S
P13CORE-057Free is currently the absence of billing rather than a setting, so it cannot be flipped or testedAn absence cannot be flipped and cannot be tested, and the whole free-beta model depends on the flip being one setting that has been exercised.M
P13DOC-001No document carries a provenance blockNo document in the repo records what validated it, so nothing can tell a description of the code from a description of an intention.M
P13DOC-004Directory READMEs and CLAUDE.md filesAn agent editing a directory has to read sixteen global rules to find the one that governs it.M
P13DOC-005nothing says where product code goes, or what the template has no opinion aboutNo document in the repo says where a founder's own product code goes, and the scaffold's only stated patterns are component-shaped.S
P13DOC-006the pinned product gate counts are stale in the pessimistic directionDEV-CHECKLIST and README pin product format-check and typecheck as failing when both are green, and README calls under-promising the same defect as over-promising.S
P13DOC-009Four files still say saas new copies the lenses into every productThe review layer became opt in and four documents outside the trim's scope still assert the old behaviour, including the one that promises a product gets the template's review capability.S
P13DOC-017reviews/verification-baseline.md is status current, wrong on half its rows, and exempt from the staleness gate by directorydocs/VERIFICATION.md sends every reader to this file for "the current failing output", and six of its twelve summary rows disagree with make report at HEAD, while check_provenance.py skips all of reviews/ as dated transcripts.S
P13DOC-024The deploy tail has four different numbers and the asserted one is outvotedtests/deploy_walk.py computes a 14-step tail with 10 unexecuted, and docs/QUEUE.md says 31 with 11, docs/DEVELOPING.md says 15 with 11, and docs/PATHS.md says 26 with 9, so the headline metric has four spellings and the asserted one is in the minority.S
P13DOC-038Two of the three priority inputs measure one axis, so half the register lands in P1value and importance are never more than one level apart on any of the 102 scored tickets and agree exactly on 65% of them, so points is effectively 2*value+urgency and 57 of 107 priced tickets land in one band.M
P13DOC-070A real-usage review that drives the product and takes screenshotsHe asked on 2026-09-14 and in substance on 2026-09-11. The one screenshot-based review that exists was done by hand, no lens requires it, and the word screenshot appears nowhere in backlog. lenses/README.md's own opening argument is that reading cannot detect absence of execution, and the visual half of the product is the part nothing executes.L
P13DOC-077Why 22 gates and 2139 tests missed seven live defectsThe owner was told the template is roughly 75% of the way to production-grade and answered "I think there's a shitton of bugs an mistakes in th ecode, so I'd prolly say 56% or so". The rate of finding defects had not dropped in two days, and nothing had classified the roughly one hundred found defects by what actually discovered each one.M
P13DOC-080BLOCKED-ON-YOU.md promises four fields per entry and 2 of 49 carry themthe owner wants what is blocked on him queryable with its context, and the file already states the format it does not keepM
P13OPS-012The teardown proves nothing about volumes, because it destroys the app and then asks the app for its volumesA forgotten volume bills with no app attached to it, and both the script and the service guide check for one in a way that cannot report anything.S
P13OPS-016make dev does not run the answerability check that two other commands havesaas doctor and saas deploy local both refuse a borrowed port and name the process holding it, and make dev, the command that suffers the defect, runs neither - reproduced at edd465d with two IPv4 listeners on one port.S
P13OPS-035Nothing configures encryption at rest, and the only backup is a manual pg_dump with no schedule, no encryption and no retentionCC.06.24 wants disk-level encryption on databases, storage and backups and CC.06.11 wants restricted backup access, and the level 2 path puts Postgres on a docker volume on an unencrypted root disk whose only backup is an operator typing a command.M
P13OPS-039Dependabot alerts are off, and no update configuration exists in either faceA vulnerability feed that is switched off reports nothing and looks identical to one reporting no vulnerabilities, which is the green-on-unverified-state shape this repo keeps finding.S
P13OPS-042Nothing proves the whole chain, because no automated run goes from empty directory to a deployed URLEvery existing test covers a piece of the path, and the one defect that mattered most lived in the joins between them.M
P13OPS-052A sign-in token is in history and not in the tree, and the history scan is red on itThe working-tree scan is clean and the history scan is not, which is the whole reason the two are separate gates - and the decision about what to do with a committed credential is the owner's, not an agent's, because both available answers cost something irreversible.S
P13OPS-056The negative control proving the migration lock is load-bearing did not break in CI, so the lock is unproven thereOn CI's first run the inverted race reported "without the lock all four runners still passed", so the negative control that exists to prove the advisory lock is load-bearing proves nothing on a GitHub runner.M
P13OPS-061The fly.io account is past its trial, so nothing in this repository can walk a deploy any moreflyctl answers every call, fly apps list and fly apps create included, with Error: trial has ended, please add a credit card. So scripts/deploy/flyio.sh up cannot run, and the deploy path this repository has walked twice - and which four contracts take criteria from - cannot be walked again by anybody here.S
P13OPS-080a downgrade that deletes rows in raw SQL is costed at zerodrops_in_downgrade reads only drop_column and drop_table, so a downgrade() whose body is op.execute('DELETE FROM ...') is costed at zero rows and assert_rollback_is_lossless prints 'nothing in those downgrade() bodies drops a table or a column, so no row is destroyed by undoing them' before destroying them. OPS-078 inverted the upgrade direction to an allowlist; the rollback direction still reads two verbs.S
P13OPS-082every gate runs saas from an interpreter no founder hascli/gates/scaffold.py:197 and cli/examples.py:278 both invoke the CLI as [sys.executable, '-m', 'cli.main'] out of .venv-verify, which carries the whole product stack. README.md tells a founder to uv tool install --editable, whose venv carries the CLI's five declared dependencies and nothing else. So every end-to-end gate exercises saas in an environment no user has, and OPS-077 - saas new writing no migration for anybody who followed the README - was green under all of them for its whole life.M
P13OPS-101jobs is installed, four schedules are registered, and the product's own deployment runs no workerInstalling jobs beside auth registers four hourly sweeps, and docker-compose.yml has no worker service while README.md and CLAUDE.md never mention make worker - so saas deploy local runs a product whose retention never runs and nothing notices.M
P13OPS-120walk.py's three shapes no longer describe what saas new produces, so fifteen and nine are both wrongmake walk-benchmark is red on main and nothing in the gate ledger says so. saas new installs invite by default, whose dependency closure is auth, authz and webauth, so the core-only shape is not core-only and the core+auth shape's saas add auth changes nothing. Two necessity probes are firing correctly and the step count they guard has to come down, which makes docs/DEV-CHECKLIST.md's fifteen and nine both wrong and section A step 6's "core is already in" wrong with them.M
P13OPS-134A product's ruff format rewrites the python inside its own markdown, and format-check is red on itskeleton/pyproject.toml.j2 has no [tool.ruff.format] table, so a product's make format-check is red on any markdown file holding a python fence and make format silently rewrites the evidence in it. The template excluded *.md from the formatter for exactly this reason and the kit never got the change, which is OPS-092's shape again.S
P13OPS-137A shared resource with no declared separation is refused, not notedadr-013 allows a product to share tier-two infrastructure only if the separation carries its own command, its measured cost and what is unavailable while it runs. Without a registry declaring those, the tier is prose and no gate can read it - the same reason personal_data.py, egress.py and SHELL_CONTEXT are declarations beside the code rather than documents describing the code.M
P13OPS-138A scaffolded product must reference none of the factory's infrastructureadr-013 says standalone has to mean something checkable rather than a claim in a README. A product tree containing an account id, an org-level resource name, a runner group or a bucket it does not own is coupled to the factory whatever the documentation says. This is the property that makes the whole decision enforceable, and it is decidable by reading a scaffolded tree.M
P13OPS-140The shipped restore verb cannot restore into a destroyed database, and its prompt says it canthe first restore ever run in this project found two cases where scripts/deploy/hetzner.sh restore refuses, and one of the two is the case the verb exists for - a box that is gone. Both were measured against a scaffolded product on 2026-09-16 and both are in docs/RESTORE.md.S
P13OPS-141A scaffolded product has no backup command, so the only one lives in the factoryadr-013 Tier 3 says a product is a copy of the code with no link back, and the only backup and restore verbs in this repository are scripts/deploy/hetzner.sh, which never travels. A standalone product can rehearse a restore since OPS-140 and still cannot take a backup with a command it owns.M
P13PROD-003Shared phone bookThe smallest product that needs group-scoped authorization, so it forces the thing AUTH-008 describes and scratchpad could not reach.L
P13PROD-005Nobody can be removed from a shared phone book, so the half of the invariant about losing a role has no callerPROD-003 grants roles and never takes one away, so a demoted admin and a removed member are both unreachable through the API and the three attacks about them cannot be written.M
P13PROD-007File drop, the smallest product whose erasure has to delete bytescomponents/files has no caller in any example. The interesting half is not the upload, it is that erase_subject must reach object storage and not only rows, which is declared as the indirect disposition and proven only at template level.L
P13PROD-009TimeMachine, the session lifecycle a stopwatch does not haveStart, pause, resume, stop and abort are the whole product, and abort is the one a stopwatch has never had. Every route here derives the session from the caller and takes no id, which is PROD-002's argument applied to a row that is identified by being open rather than by being owned.M
P13PROD-011TimeMachine, one open session across devices that were offlineThis is the rung. A timer runs while a phone is in a tunnel, and two devices can both believe a session is open without anybody doing anything wrong, so PROD-006's invariant is violated by physics rather than by an attacker. No product on the ladder has had a uniqueness constraint that a network partition can break, and adr-004 has never had a caller that needed one.L
P13PROD-023The shop's address is still one string, and the fields it should be exist nowCOMP-059 built the fields and declared them. Until the shop moves onto them, the only product that has the problem still has it.M

From docs/state.json -> backlog.tickets, restricted to backlog.frontier. Priority is the derivation value + urgency, never the written field - python3.12 scripts/score.py --table is the rule.

Agents

Whether an agent is running right now is not knowable from this tree, and this page does not guess. A worktree outlives the agent that made it - the root CLAUDE.md records four left behind by one laptop sleep, one of them holding main - so counting worktrees counts abandonment, not activity. DISPATCH.md is the register of what is in flight and it is maintained by hand.

agents running
unknown
tickets marked in progress
5
TicketTitleBranch
COMP-086An invitation is a link a founder copies, and there is no messageatomic/comp-086/a-message-beside-the-link
CORE-057Free is currently the absence of billing rather than a setting, so it cannot be flipped or testedatomic/core/billing-mode
CORE-067The personal-data gate is table-level, so a new column on a declared table walks past itatomic/core-067/column-coverage
OPS-038The repository's own protection settings are clicks, and the OpenTofu that would replace them cannot be applied on the current GitHub planno branch named
OPS-056The negative control proving the migration lock is load-bearing did not break in CI, so the lock is unproven thereatomic/invisible-tests/race-control

The worktree census is deliberately not published. It is read from the machine the generator ran on, so it is not a fact about this repository, and its rows are absolute checkout paths and other agents' branch names. Neither belongs on a public hostname.

Locally: git worktree list, or make dashboard-live to see it beside everything else.

In-progress tickets from docs/state.json -> backlog.tickets, where status is in_progress. Liveness is from nowhere, because nothing in the tree records it - DISPATCH.md is the hand-written register and docs/QUEUE.md is what gets an agent next.

How this project works

The machine rather than its output. Every document below is rendered here in full, so reading it does not mean cloning a repository. The prose is set in a serif and the dashboard is not, which is the only signal you need for which half of this site you are in.

17 terms defined, and the first 48 of them

Terms this repository coined or bent. A word owned by an RFC or a vendor lives in docs/BORROWED-TERMS.md instead, because a glossary that restates a standard is wrong the day the standard moves and wrong in a way nobody notices.

read the glossary in place →

Rendered from docs/PURPOSE.md, docs/GLOSSARY.md, docs/METHOD.md, docs/PROCESS.md, docs/PLANNING.md, docs/DELEGATION.md and docs/AI-LED-DEVELOPMENT.md at generate time.

The dependency graph

62 edges over 245 dispatchable tickets, and only 15 of those edges still hold anything back. The graph is almost empty, which is why nothing can say what to work on next: 205 unbuilt tickets have no edge at all, and the 29 fragments that do are not one graph.

edges
62
still blocking
15of those
fragments
29
largest fragment
11nodes
no edge at all
205

draw all 29 fragments, and the 205-dot field →

From docs/state.json -> backlog.graph, undirected for components. An edge whose upstream ticket is already built is counted as an edge and not as a blocker, which is why edges and still blocking disagree by 47.